IP Geo Block - Version 3.0.1.2

Version Description

  • Bug fix: Fix the blocking issue in some environments when upgrading from 2.2.9.1 to 3.0.0.
  • Bug fix: Fix the blocking issue at opening a new window via context menu on dashboard.
  • Bug fix: Fix the potential issue of 500 Internal error in cron job.
  • Improvement: Revive 410 Gone for response code.
  • Improvement: Prevent the issue of resetting matching rule and country code at upgrading.
Download this release

Release Info

Developer tokkonopapa
Plugin Icon 128x128 IP Geo Block
Version 3.0.1.2
Comparing to
See all releases

Version 3.0.1.2

Files changed (114) hide show
  1. LICENSE.txt +339 -0
  2. README.txt +898 -0
  3. admin/class-ip-geo-block-admin.php +982 -0
  4. admin/css/admin.css +379 -0
  5. admin/css/admin.min.css +2 -0
  6. admin/css/fonts/LICENSE +4 -0
  7. admin/css/fonts/footable.eot +0 -0
  8. admin/css/fonts/footable.svg +78 -0
  9. admin/css/fonts/footable.ttf +0 -0
  10. admin/css/fonts/footable.woff +0 -0
  11. admin/css/footable.core.min.css +10 -0
  12. admin/includes/class-admin-ajax.php +486 -0
  13. admin/includes/class-admin-rewrite.php +340 -0
  14. admin/includes/tab-accesslog.php +150 -0
  15. admin/includes/tab-attribution.php +41 -0
  16. admin/includes/tab-geolocation.php +94 -0
  17. admin/includes/tab-settings.php +1334 -0
  18. admin/includes/tab-statistics.php +290 -0
  19. admin/js/admin.js +949 -0
  20. admin/js/admin.min.js +6 -0
  21. admin/js/authenticate.js +396 -0
  22. admin/js/authenticate.min.js +6 -0
  23. admin/js/footable.min.js +26 -0
  24. admin/js/gmap.js +123 -0
  25. admin/js/gmap.min.js +8 -0
  26. admin/js/whois.js +136 -0
  27. admin/js/whois.min.js +8 -0
  28. classes/class-ip-geo-block-actv.php +90 -0
  29. classes/class-ip-geo-block-apis.php +688 -0
  30. classes/class-ip-geo-block-cron.php +350 -0
  31. classes/class-ip-geo-block-lkup.php +128 -0
  32. classes/class-ip-geo-block-load.php +160 -0
  33. classes/class-ip-geo-block-logs.php +690 -0
  34. classes/class-ip-geo-block-opts.php +425 -0
  35. classes/class-ip-geo-block-util.php +515 -0
  36. classes/class-ip-geo-block.php +880 -0
  37. database/index.php +3 -0
  38. includes/Net/DNS2.php +1427 -0
  39. includes/Net/DNS2/BitMap.php +254 -0
  40. includes/Net/DNS2/Cache.php +305 -0
  41. includes/Net/DNS2/Cache/File.php +242 -0
  42. includes/Net/DNS2/Cache/Shm.php +305 -0
  43. includes/Net/DNS2/Exception.php +142 -0
  44. includes/Net/DNS2/Header.php +282 -0
  45. includes/Net/DNS2/Lookups.php +552 -0
  46. includes/Net/DNS2/Packet.php +449 -0
  47. includes/Net/DNS2/Packet/Request.php +217 -0
  48. includes/Net/DNS2/Packet/Response.php +194 -0
  49. includes/Net/DNS2/PrivateKey.php +424 -0
  50. includes/Net/DNS2/Question.php +244 -0
  51. includes/Net/DNS2/RR.php +641 -0
  52. includes/Net/DNS2/RR/A.php +156 -0
  53. includes/Net/DNS2/RR/AAAA.php +177 -0
  54. includes/Net/DNS2/RR/AFSDB.php +174 -0
  55. includes/Net/DNS2/RR/ANY.php +129 -0
  56. includes/Net/DNS2/RR/APL.php +343 -0
  57. includes/Net/DNS2/RR/ATMA.php +210 -0
  58. includes/Net/DNS2/RR/CAA.php +179 -0
  59. includes/Net/DNS2/RR/CDNSKEY.php +77 -0
  60. includes/Net/DNS2/RR/CDS.php +77 -0
  61. includes/Net/DNS2/RR/CERT.php +292 -0
  62. includes/Net/DNS2/RR/CNAME.php +153 -0
  63. includes/Net/DNS2/RR/CSYNC.php +203 -0
  64. includes/Net/DNS2/RR/DHCID.php +207 -0
  65. includes/Net/DNS2/RR/DLV.php +75 -0
  66. includes/Net/DNS2/RR/DNAME.php +153 -0
  67. includes/Net/DNS2/RR/DNSKEY.php +198 -0
  68. includes/Net/DNS2/RR/DS.php +209 -0
  69. includes/Net/DNS2/RR/EID.php +130 -0
  70. includes/Net/DNS2/RR/EUI48.php +187 -0
  71. includes/Net/DNS2/RR/EUI64.php +188 -0
  72. includes/Net/DNS2/RR/HINFO.php +175 -0
  73. includes/Net/DNS2/RR/HIP.php +287 -0
  74. includes/Net/DNS2/RR/IPSECKEY.php +386 -0
  75. includes/Net/DNS2/RR/ISDN.php +190 -0
  76. includes/Net/DNS2/RR/KEY.php +85 -0
  77. includes/Net/DNS2/RR/KX.php +179 -0
  78. includes/Net/DNS2/RR/L32.php +180 -0
  79. includes/Net/DNS2/RR/L64.php +187 -0
  80. includes/Net/DNS2/RR/LOC.php +440 -0
  81. includes/Net/DNS2/RR/LP.php +177 -0
  82. includes/Net/DNS2/RR/MX.php +175 -0
  83. includes/Net/DNS2/RR/NAPTR.php +231 -0
  84. includes/Net/DNS2/RR/NID.php +187 -0
  85. includes/Net/DNS2/RR/NIMLOC.php +130 -0
  86. includes/Net/DNS2/RR/NS.php +153 -0
  87. includes/Net/DNS2/RR/NSAP.php +262 -0
  88. includes/Net/DNS2/RR/NSEC.php +184 -0
  89. includes/Net/DNS2/RR/NSEC3.php +310 -0
  90. includes/Net/DNS2/RR/NSEC3PARAM.php +220 -0
  91. includes/Net/DNS2/RR/OPENPGPKEY.php +159 -0
  92. includes/Net/DNS2/RR/OPT.php +292 -0
  93. includes/Net/DNS2/RR/PTR.php +152 -0
  94. includes/Net/DNS2/RR/PX.php +186 -0
  95. includes/Net/DNS2/RR/RP.php +167 -0
  96. includes/Net/DNS2/RR/RRSIG.php +329 -0
  97. includes/Net/DNS2/RR/RT.php +175 -0
  98. includes/Net/DNS2/RR/SIG.php +459 -0
  99. includes/Net/DNS2/RR/SOA.php +240 -0
  100. includes/Net/DNS2/RR/SPF.php +75 -0
  101. includes/Net/DNS2/RR/SRV.php +186 -0
  102. includes/Net/DNS2/RR/SSHFP.php +244 -0
  103. includes/Net/DNS2/RR/TA.php +75 -0
  104. includes/Net/DNS2/RR/TALINK.php +171 -0
  105. includes/Net/DNS2/RR/TKEY.php +307 -0
  106. includes/Net/DNS2/RR/TLSA.php +194 -0
  107. includes/Net/DNS2/RR/TSIG.php +504 -0
  108. includes/Net/DNS2/RR/TXT.php +177 -0
  109. includes/Net/DNS2/RR/URI.php +183 -0
  110. includes/Net/DNS2/RR/WKS.php +235 -0
  111. includes/Net/DNS2/RR/X25.php +160 -0
  112. includes/Net/DNS2/Resolver.php +332 -0
  113. includes/Net/DNS2/Socket.php +190 -0
  114. includes/Net/DNS2/Socket/Sockets.php +5 -0
LICENSE.txt ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ Preamble
10
+
11
+ The licenses for most software are designed to take away your
12
+ freedom to share and change it. By contrast, the GNU General Public
13
+ License is intended to guarantee your freedom to share and change free
14
+ software--to make sure the software is free for all its users. This
15
+ General Public License applies to most of the Free Software
16
+ Foundation's software and to any other program whose authors commit to
17
+ using it. (Some other Free Software Foundation software is covered by
18
+ the GNU Lesser General Public License instead.) You can apply it to
19
+ your programs, too.
20
+
21
+ When we speak of free software, we are referring to freedom, not
22
+ price. Our General Public Licenses are designed to make sure that you
23
+ have the freedom to distribute copies of free software (and charge for
24
+ this service if you wish), that you receive source code or can get it
25
+ if you want it, that you can change the software or use pieces of it
26
+ in new free programs; and that you know you can do these things.
27
+
28
+ To protect your rights, we need to make restrictions that forbid
29
+ anyone to deny you these rights or to ask you to surrender the rights.
30
+ These restrictions translate to certain responsibilities for you if you
31
+ distribute copies of the software, or if you modify it.
32
+
33
+ For example, if you distribute copies of such a program, whether
34
+ gratis or for a fee, you must give the recipients all the rights that
35
+ you have. You must make sure that they, too, receive or can get the
36
+ source code. And you must show them these terms so they know their
37
+ rights.
38
+
39
+ We protect your rights with two steps: (1) copyright the software, and
40
+ (2) offer you this license which gives you legal permission to copy,
41
+ distribute and/or modify the software.
42
+
43
+ Also, for each author's protection and ours, we want to make certain
44
+ that everyone understands that there is no warranty for this free
45
+ software. If the software is modified by someone else and passed on, we
46
+ want its recipients to know that what they have is not the original, so
47
+ that any problems introduced by others will not reflect on the original
48
+ authors' reputations.
49
+
50
+ Finally, any free program is threatened constantly by software
51
+ patents. We wish to avoid the danger that redistributors of a free
52
+ program will individually obtain patent licenses, in effect making the
53
+ program proprietary. To prevent this, we have made it clear that any
54
+ patent must be licensed for everyone's free use or not licensed at all.
55
+
56
+ The precise terms and conditions for copying, distribution and
57
+ modification follow.
58
+
59
+ GNU GENERAL PUBLIC LICENSE
60
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
+
62
+ 0. This License applies to any program or other work which contains
63
+ a notice placed by the copyright holder saying it may be distributed
64
+ under the terms of this General Public License. The "Program", below,
65
+ refers to any such program or work, and a "work based on the Program"
66
+ means either the Program or any derivative work under copyright law:
67
+ that is to say, a work containing the Program or a portion of it,
68
+ either verbatim or with modifications and/or translated into another
69
+ language. (Hereinafter, translation is included without limitation in
70
+ the term "modification".) Each licensee is addressed as "you".
71
+
72
+ Activities other than copying, distribution and modification are not
73
+ covered by this License; they are outside its scope. The act of
74
+ running the Program is not restricted, and the output from the Program
75
+ is covered only if its contents constitute a work based on the
76
+ Program (independent of having been made by running the Program).
77
+ Whether that is true depends on what the Program does.
78
+
79
+ 1. You may copy and distribute verbatim copies of the Program's
80
+ source code as you receive it, in any medium, provided that you
81
+ conspicuously and appropriately publish on each copy an appropriate
82
+ copyright notice and disclaimer of warranty; keep intact all the
83
+ notices that refer to this License and to the absence of any warranty;
84
+ and give any other recipients of the Program a copy of this License
85
+ along with the Program.
86
+
87
+ You may charge a fee for the physical act of transferring a copy, and
88
+ you may at your option offer warranty protection in exchange for a fee.
89
+
90
+ 2. You may modify your copy or copies of the Program or any portion
91
+ of it, thus forming a work based on the Program, and copy and
92
+ distribute such modifications or work under the terms of Section 1
93
+ above, provided that you also meet all of these conditions:
94
+
95
+ a) You must cause the modified files to carry prominent notices
96
+ stating that you changed the files and the date of any change.
97
+
98
+ b) You must cause any work that you distribute or publish, that in
99
+ whole or in part contains or is derived from the Program or any
100
+ part thereof, to be licensed as a whole at no charge to all third
101
+ parties under the terms of this License.
102
+
103
+ c) If the modified program normally reads commands interactively
104
+ when run, you must cause it, when started running for such
105
+ interactive use in the most ordinary way, to print or display an
106
+ announcement including an appropriate copyright notice and a
107
+ notice that there is no warranty (or else, saying that you provide
108
+ a warranty) and that users may redistribute the program under
109
+ these conditions, and telling the user how to view a copy of this
110
+ License. (Exception: if the Program itself is interactive but
111
+ does not normally print such an announcement, your work based on
112
+ the Program is not required to print an announcement.)
113
+
114
+ These requirements apply to the modified work as a whole. If
115
+ identifiable sections of that work are not derived from the Program,
116
+ and can be reasonably considered independent and separate works in
117
+ themselves, then this License, and its terms, do not apply to those
118
+ sections when you distribute them as separate works. But when you
119
+ distribute the same sections as part of a whole which is a work based
120
+ on the Program, the distribution of the whole must be on the terms of
121
+ this License, whose permissions for other licensees extend to the
122
+ entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or with a work based on the Program) on a volume of
131
+ a storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at least three
143
+ years, to give any third party, for a charge no more than your
144
+ cost of physically performing source distribution, a complete
145
+ machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for noncommercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy the source along with the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sublicense or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties to
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgment or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court order, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is intended to apply in other
213
+ circumstances.
214
+
215
+ It is not the purpose of this section to induce you to infringe any
216
+ patents or other property right claims or to contest validity of any
217
+ such claims; this section has the sole purpose of protecting the
218
+ integrity of the free software distribution system, which is
219
+ implemented by public license practices. Many people have made
220
+ generous contributions to the wide range of software distributed
221
+ through that system in reliance on consistent application of that
222
+ system; it is up to the author/donor to decide if he or she is willing
223
+ to distribute software through any other system and a licensee cannot
224
+ impose that choice.
225
+
226
+ This section is intended to make thoroughly clear what is believed to
227
+ be a consequence of the rest of this License.
228
+
229
+ 8. If the distribution and/or use of the Program is restricted in
230
+ certain countries either by patents or by copyrighted interfaces, the
231
+ original copyright holder who places the Program under this License
232
+ may add an explicit geographical distribution limitation excluding
233
+ those countries, so that distribution is permitted only in or among
234
+ countries not thus excluded. In such case, this License incorporates
235
+ the limitation as if written in the body of this License.
236
+
237
+ 9. The Free Software Foundation may publish revised and/or new versions
238
+ of the General Public License from time to time. Such new versions will
239
+ be similar in spirit to the present version, but may differ in detail to
240
+ address new problems or concerns.
241
+
242
+ Each version is given a distinguishing version number. If the Program
243
+ specifies a version number of this License which applies to it and "any
244
+ later version", you have the option of following the terms and conditions
245
+ either of that version or of any later version published by the Free
246
+ Software Foundation. If the Program does not specify a version number of
247
+ this License, you may choose any version ever published by the Free Software
248
+ Foundation.
249
+
250
+ 10. If you wish to incorporate parts of the Program into other free
251
+ programs whose distribution conditions are different, write to the author
252
+ to ask for permission. For software which is copyrighted by the Free
253
+ Software Foundation, write to the Free Software Foundation; we sometimes
254
+ make exceptions for this. Our decision will be guided by the two goals
255
+ of preserving the free status of all derivatives of our free software and
256
+ of promoting the sharing and reuse of software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+ POSSIBILITY OF SUCH DAMAGES.
279
+
280
+ END OF TERMS AND CONDITIONS
281
+
282
+ How to Apply These Terms to Your New Programs
283
+
284
+ If you develop a new program, and you want it to be of the greatest
285
+ possible use to the public, the best way to achieve this is to make it
286
+ free software which everyone can redistribute and change under these terms.
287
+
288
+ To do so, attach the following notices to the program. It is safest
289
+ to attach them to the start of each source file to most effectively
290
+ convey the exclusion of warranty; and each file should have at least
291
+ the "copyright" line and a pointer to where the full notice is found.
292
+
293
+ <one line to give the program's name and a brief idea of what it does.>
294
+ Copyright (C) <year> <name of author>
295
+
296
+ This program is free software; you can redistribute it and/or modify
297
+ it under the terms of the GNU General Public License as published by
298
+ the Free Software Foundation; either version 2 of the License, or
299
+ (at your option) any later version.
300
+
301
+ This program is distributed in the hope that it will be useful,
302
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
303
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
+ GNU General Public License for more details.
305
+
306
+ You should have received a copy of the GNU General Public License along
307
+ with this program; if not, write to the Free Software Foundation, Inc.,
308
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
+
310
+ Also add information on how to contact you by electronic and paper mail.
311
+
312
+ If the program is interactive, make it output a short notice like this
313
+ when it starts in an interactive mode:
314
+
315
+ Gnomovision version 69, Copyright (C) year name of author
316
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
+ This is free software, and you are welcome to redistribute it
318
+ under certain conditions; type `show c' for details.
319
+
320
+ The hypothetical commands `show w' and `show c' should show the appropriate
321
+ parts of the General Public License. Of course, the commands you use may
322
+ be called something other than `show w' and `show c'; they could even be
323
+ mouse-clicks or menu items--whatever suits your program.
324
+
325
+ You should also get your employer (if you work as a programmer) or your
326
+ school, if any, to sign a "copyright disclaimer" for the program, if
327
+ necessary. Here is a sample; alter the names:
328
+
329
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
+
332
+ <signature of Ty Coon>, 1 April 1989
333
+ Ty Coon, President of Vice
334
+
335
+ This General Public License does not permit incorporating your program into
336
+ proprietary programs. If your program is a subroutine library, you may
337
+ consider it more useful to permit linking proprietary applications with the
338
+ library. If this is what you want to do, use the GNU Lesser General
339
+ Public License instead of this License.
README.txt ADDED
@@ -0,0 +1,898 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === IP Geo Block ===
2
+ Contributors: tokkonopapa
3
+ Donate link:
4
+ Tags: security, firewall, brute force, vulnerability, login, wp-admin, admin, ajax, xmlrpc, comment, pingback, trackback, spam, IP address, geo, geolocation, buddypress, bbPress
5
+ Requires at least: 3.7
6
+ Tested up to: 4.7.2
7
+ Stable tag: 3.0.1.2
8
+ License: GPLv2 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ It blocks spam posts, login attempts and malicious access to the back-end
12
+ requested from the specific countries, and also prevents zero-day exploit.
13
+
14
+ == Description ==
15
+
16
+ A considerable number of WordPress vulnerabilities in plugins and themes have
17
+ been disclosed every month. You can easily find them at
18
+ [WPScan Vulnerability Database](https://wpvulndb.com/ "WPScan Vulnerability Database")
19
+ and
20
+ [Exploits Database](https://www.exploit-db.com/ "Exploits Database by Offensive Security")
21
+ for example. It means that many WordPress sites can be always exposed to the
22
+ threats of being exploited caused by those vulnerabilities.
23
+
24
+ This plugin protects your site against such threats of attack to the back-end
25
+ of your site not only by blocking requests from undesired countries but also
26
+ with the original feature 'Zero-day Exploit Prevention' (WP-ZEP).
27
+
28
+ And it also blocks undesired requests to the login form (login attempt),
29
+ comment form (spam and trackback) and XML-RPC (login attempt and pingback).
30
+
31
+ Up to version 2.x, this plugin had been dedicated to protect the back-end of
32
+ your site. From version 3.x, it becomes to be able to block access to your
33
+ public facing pages, aka front-end. See
34
+ [this analysis](http://www.ipgeoblock.com/codex/analysis-of-attack-vectors.html "Analysis of Attack Vectors | IP Geo Block")
35
+ about protection performance against 50 samples of vulnerable plugins.
36
+
37
+ = Features =
38
+
39
+ * **Immigration control:**
40
+ Access to the basic and important entrances into the back-end such as
41
+ `wp-comments-post.php`, `xmlrpc.php`, `wp-login.php`, `wp-signup.php`,
42
+ `wp-admin/admin.php`, `wp-admin/admin-ajax.php`, `wp-admin/admin-post.php`
43
+ will be validated by means of a country code based on IP address. It allows
44
+ you to configure either whitelist or blacklist to specify the countires.
45
+
46
+ * **Zero-day Exploit Prevention:**
47
+ The original feature "**Z**ero-day **E**xploit **P**revention for WP"
48
+ (WP-ZEP) is simple but still smart and strong enough to block any malicious
49
+ accesses to `wp-admin/*.php`, `plugins/*.php` and `themes/*.php` even from
50
+ the permitted countries. It will protect your site against certain types of
51
+ attack such as CSRF, LFI, SQLi, XSS and so on, **even if you have some in
52
+ your site**. Find more details in
53
+ [FAQ](https://wordpress.org/plugins/ip-geo-block/faq/ "IP Geo Block - WordPress Plugins")
54
+ and
55
+ [this plugin's blog](http://www.ipgeoblock.com/article/how-wpzep-works.html "How does WP-ZEP prevent zero-day attack? | IP Geo Block").
56
+
57
+ * **Guard against login attempts:**
58
+ In order to prevent hacking through the login form and XML-RPC by
59
+ brute-force and the reverse-brute-force attacks, the number of login
60
+ attempts will be limited per IP address even from the permitted countries.
61
+
62
+ * **Protection of wp-config.php:**
63
+ A malicious request to try to expose `wp-config.php` via vulnerable plugins
64
+ or themes can be blocked. A numerous such attacks can be found in
65
+ [this article](http://www.ipgeoblock.com/article/exposure-of-wp-config-php.html "Prevent exposure of wp-config.php").
66
+
67
+ * **Minimize server load against brute-force attacks:**
68
+ You can configure this plugin as a
69
+ [Must Use Plugins](https://codex.wordpress.org/Must_Use_Plugins "Must Use Plugins &laquo; WordPress Codex")
70
+ which would be loaded prior to regular plugins and can massively
71
+ [reduce the load on server](http://www.ipgeoblock.com/codex/validation-timing.html "Validation timing | IP Geo Block").
72
+ And furthermore, a cache mechanism for the fetched IP addresses and country
73
+ code can help to reduce load on the server against the burst accesses with
74
+ a short period of time.
75
+
76
+ * **Support of BuddyPress and bbPress:**
77
+ You can configure this plugin such that a registered user can login as the
78
+ membership from anywhere, but a request such as a new user registration,
79
+ lost password, creating a new topic, and subscribing comment is blocked by
80
+ the country code. It is suitable for
81
+ [BuddyPress](https://wordpress.org/plugins/buddypress/ "WordPress › BuddyPress « WordPress Plugins")
82
+ and [bbPress](https://wordpress.org/plugins/bbpress/ "WordPress › bbPress « WordPress Plugins")
83
+ to help reducing spams.
84
+
85
+ * **Referrer suppressor for external links:**
86
+ When you click an external hyperlink on admin screen, http referrer will be
87
+ eliminated to hide a footprint of your site.
88
+
89
+ * **Multiple source of IP Geolocation databases:**
90
+ Free IP Geolocation database and REST APIs are installed into this plugin to
91
+ get a country code from an IP address.
92
+ [MaxMind](http://www.maxmind.com "MaxMind - IP Geolocation and Online Fraud Prevention")
93
+ GeoLite free databases and
94
+ [IP2Location](http://www.ip2location.com/ "IP Address Geolocation to Identify Website Visitor's Geographical Location")
95
+ LITE databases can be available in this plugin. Those will be downloaded
96
+ and updated (once a month) automatically.
97
+
98
+ * **Customizing response:**
99
+ HTTP response code can be selectable as `403 Forbidden` to deny access pages,
100
+ `404 Not Found` to hide pages or even `200 OK` to redirect to the top page.
101
+ You can also have the custom error page (for example `403.php`) in your theme
102
+ template directory or child theme directory to fit your theme.
103
+
104
+ * **Validation logs:**
105
+ Logs will be recorded into MySQL data table to audit posting pattern under
106
+ the specified condition.
107
+
108
+ * **Cooperation with full spec security plugin:**
109
+ This plugin is simple and lite enough to be able to cooperate with other
110
+ full spec security plugin such as
111
+ [Wordfence Security](https://wordpress.org/plugins/wordfence/ "WordPress › Wordfence Security « WordPress Plugins")
112
+ (because country bloking is available only for premium users). See
113
+ [this report](http://www.ipgeoblock.com/codex/page-speed-performance.html "Page speed performance | IP Geo Block")
114
+ about page speed performance.
115
+
116
+ * **Extendability:**
117
+ "Settings minimum, Customizability maximum" is the basic concept of this
118
+ plugin. You can customize the behavior of this plugin via `add_filter()`
119
+ with pre-defined filter hook. See various use cases in
120
+ [the documents](http://www.ipgeoblock.com/codex/ "Codex | IP Geo Block")
121
+ and
122
+ [samples.php](https://github.com/tokkonopapa/WordPress-IP-Geo-Block/blob/master/ip-geo-block/samples.php "WordPress-IP-Geo-Block/samples.php at master - tokkonopapa/WordPress-IP-Geo-Block - GitHub")
123
+ bundled within this package.
124
+
125
+ * **Self blocking prevention and easy rescue:**
126
+ Most of users do not prefer themselves to be blocked. This plugin prevents
127
+ such a sad thing unless you force it. And futhermore, if such a situation
128
+ occurs, you can
129
+ [rescue yourself](http://www.ipgeoblock.com/codex/what-should-i-do-when-i-m-locked-out.html "What should I do when I'm locked out? | IP Geo Block")
130
+ easily.
131
+
132
+ * **Clean uninstallation:**
133
+ Nothing is left in your precious mySQL database after uninstallation. So you
134
+ can feel free to install and activate to make a trial of this plugin's
135
+ functionality. Several days later, you'll find many undesirable accesses in
136
+ your validation logs if all validation targets are enabled.
137
+
138
+ = Attribution =
139
+
140
+ This package includes GeoLite library distributed by MaxMind, available from
141
+ [MaxMind](http://www.maxmind.com "MaxMind - IP Geolocation and Online Fraud Prevention"),
142
+ and also includes IP2Location open source libraries available from
143
+ [IP2Location](http://www.ip2location.com "IP Address Geolocation to Identify Website Visitor's Geographical Location").
144
+
145
+ Also thanks for providing the following great services and REST APIs for free.
146
+
147
+ * [http://freegeoip.net/](http://freegeoip.net/ "freegeoip.net: FREE IP Geolocation Web Service") (IPv4 / free)
148
+ * [http://ipinfo.io/](http://ipinfo.io/ "ipinfo.io - ip address information including geolocation, hostname and network details") (IPv4, IPv6 / free)
149
+ * [http://geoip.nekudo.com/](http://geoip.nekudo.com/ "Free IP GeoLocation/GeoIp API - geoip.nekudo.com") (IPv4, IPv6 / free)
150
+ * [http://xhanch.com/](http://xhanch.com/xhanch-api-ip-get-detail/ "Xhanch API &#8211; IP Get Detail | Xhanch Studio") (IPv4 / free)
151
+ * [http://geoiplookup.net/](http://geoiplookup.net/ "What Is My IP Address | GeoIP Lookup") (IPv4, IPv6 / free)
152
+ * [http://ip-api.com/](http://ip-api.com/ "IP-API.com - Free Geolocation API") (IPv4, IPv6 / free for non-commercial use)
153
+ * [http://ipinfodb.com/](http://ipinfodb.com/ "IPInfoDB | Free IP Address Geolocation Tools") (IPv4, IPv6 / free for registered user, need API key)
154
+
155
+ = Development =
156
+
157
+ Development of this plugin is promoted at
158
+ [WordPress-IP-Geo-Block](https://github.com/tokkonopapa/WordPress-IP-Geo-Block "tokkonopapa/WordPress-IP-Geo-Block - GitHub")
159
+ and class libraries to handle geo-location database are developed separately
160
+ as "add-in"s at
161
+ [WordPress-IP-Geo-API](https://github.com/tokkonopapa/WordPress-IP-Geo-API "tokkonopapa/WordPress-IP-Geo-API - GitHub").
162
+ All contributions will always be welcome. Or visit my
163
+ [development blog](http://www.ipgeoblock.com/ "IP Geo Block").
164
+
165
+ == Installation ==
166
+
167
+ = Using The WordPress Dashboard =
168
+
169
+ 1. Navigate to the 'Add New' in the plugins dashboard
170
+ 2. Search for 'IP Geo Block'
171
+ 3. Click 'Install Now'
172
+ 4. Activate the plugin on the Plugin dashboard
173
+ 5. Try 'Best settings' button for easy setup at the bottom of this plugin's
174
+ setting page.
175
+
176
+ Please refer to
177
+ [the document](http://www.ipgeoblock.com/codex/ "Codex | IP Geo Block")
178
+ or following descriptions for your best setup.
179
+
180
+ = Validation rule settings =
181
+
182
+ * **Matching rule**
183
+ Choose either `White list` (recommended) or `Black list` to specify the
184
+ countries from which you want to pass or block.
185
+
186
+ * **Country code for matching rule**
187
+ Specify the country code with two letters (see
188
+ [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements "ISO 3166-1 alpha-2 - Wikipedia, the free encyclopedia")
189
+ ). Each of them should be separated by comma.
190
+
191
+ * **White/Black list of extra IPs for prior validation**
192
+ The list of extra IP addresses prior to the validation of country code.
193
+ [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing "Classless Inter-Domain Routing - Wikipedia, the free encyclopedia")
194
+ is acceptable to specify the range.
195
+
196
+ * **$_SERVER keys for extra IPs**
197
+ Additional IP addresses will be validated if some of keys in `$_SERVER`
198
+ variable are specified in this textfield. Typically `HTTP_X_FORWARDED_FOR`.
199
+
200
+ * **Bad signatures in query**
201
+ It validates malicious signatures independently of **Block by country** and
202
+ **Prevent Zero-day Exploit** for the target **Admin area**,
203
+ **Admin ajax/post**, **Plugins area** and **Themes area**.
204
+ Typically, `/wp-config.php` and `/passwd`.
205
+
206
+ * **Response code**
207
+ Choose one of the
208
+ [response code](http://tools.ietf.org/html/rfc2616#section-10 "RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1")
209
+ to be sent when it blocks a comment.
210
+ The 2xx code will lead to your top page, the 3xx code will redirect to
211
+ [Black Hole Server](http://blackhole.webpagetest.org/),
212
+ the 4xx code will lead to WordPress error page, and the 5xx will pretend
213
+ an server error.
214
+
215
+ * **Validation timing**
216
+ Choose **"init" action hook** or **"mu-plugins" (ip-geo-block-mu.php)** to
217
+ specify the timing of validation.
218
+
219
+ = Back-end target settings =
220
+
221
+ * **Comment post**
222
+ Validate post to `wp-comment-post.php`. Comment post and trackback will be
223
+ validated.
224
+
225
+ * **XML-RPC**
226
+ Validate access to `xmlrpc.php`. Pingback and other remote command with
227
+ username and password will be validated.
228
+
229
+ * **Login form**
230
+ Validate access to `wp-login.php` and `wp-signup.php`.
231
+
232
+ * **Admin area**
233
+ Validate access to `wp-admin/*.php`.
234
+
235
+ * **Admin ajax/post**
236
+ Validate access to `wp-admin/admin-(ajax|post)*.php`.
237
+
238
+ * **Plugins area**
239
+ Validate direct access to plugins. Typically `wp-content/plugins/…/*.php`.
240
+
241
+ * **Themes area**
242
+ Validate direct access to themes. Typically `wp-content/themes/…/*.php`.
243
+
244
+ = Front-end target settings =
245
+
246
+ * **Block by country**
247
+ Enables validation of country code on public facing pages.
248
+
249
+ * **Matching rule**
250
+ Same as **Validation target settings** but can be set independently.
251
+
252
+ * **Validation target**
253
+ Specify the single and archive page by post type, category and tag as
254
+ blocking target.
255
+
256
+ * **UA string and qualification**
257
+ Additional rules targeted at SEO which can specify acceptable requests
258
+ based on user agent.
259
+
260
+ * **Simulation mode**
261
+ You can simulate the 'blocking on front-end' functionality before deploying.
262
+
263
+ = Geolocation API settings =
264
+
265
+ * **API selection and key settings**
266
+ If you wish to use `IPInfoDB`, you should register at
267
+ [their site](http://ipinfodb.com/ "IPInfoDB | Free IP Address Geolocation Tools")
268
+ to get a free API key and set it into the textfield. And `ip-api.com` and
269
+ `Smart-IP.net` require non-commercial use.
270
+
271
+ = Local database settings settings =
272
+
273
+ * **Auto updating (once a month)**
274
+ If `Enable`, Maxmind GeoLite database will be downloaded automatically by
275
+ WordPress cron job.
276
+
277
+ = Record settings =
278
+
279
+ * **Record validation statistics**
280
+ If `Enable`, you can see `Statistics of validation` on Statistics tab.
281
+
282
+ * **Record validation logs**
283
+ If you choose anything but `Disable`, you can see `Validation logs` on
284
+ Logs tab.
285
+
286
+ * **$_POST keys in logs**
287
+ Normally, you can see just keys at `$_POST data:` on Logs tab. If you put
288
+ some of interested keys into this textfield, you can see the value of key
289
+ like `key=value`.
290
+
291
+ * **Anonymize IP address**
292
+ It will mask the last three digits of IP address when it is recorded into
293
+ the log.
294
+
295
+ = Cache settings =
296
+
297
+ * **Expiration time [sec]**
298
+ Maximum time in sec to keep cache.
299
+
300
+ * **Garbage collection period [sec]**
301
+ Period of garbage collection to clean cache.
302
+
303
+ = Submission settings =
304
+
305
+ * **Text position on comment form**
306
+ If you want to put some text message on your comment form, please choose
307
+ `Top` or `Bottom` and put text with some tags into the **Text message on
308
+ comment form** textfield.
309
+
310
+ = Plugin settings =
311
+
312
+ * **Remove settings at uninstallation**
313
+ If you checked this option, all settings will be removed when this plugin
314
+ is uninstalled for clean uninstalling.
315
+
316
+ == Frequently Asked Questions ==
317
+
318
+ = Does it support multisite? =
319
+
320
+ It works on multisite, but there's no network setting at this moment.
321
+
322
+ = I was locked down. What shall I do? =
323
+
324
+ Activate the following codes at the bottom of `ip-geo-block.php` and upload
325
+ it via FTP.
326
+
327
+ `/**
328
+ * Invalidate blocking behavior in case yourself is locked out.
329
+ *
330
+ * How to use: Activate the following code and upload this file via FTP.
331
+ */
332
+ /* -- EDIT THIS LINE AND ACTIVATE THE FOLLOWING FUNCTION -- */
333
+ function ip_geo_block_emergency( $validate ) {
334
+ $validate['result'] = 'passed';
335
+ return $validate;
336
+ }
337
+ add_filter( 'ip-geo-block-login', 'ip_geo_block_emergency' );
338
+ add_filter( 'ip-geo-block-admin', 'ip_geo_block_emergency' );
339
+ // */`
340
+
341
+ Then "**Clear cache**" at "**Statistics**" tab on your dashborad. Remember
342
+ that you should upload the original one to deactivate above feature.
343
+
344
+ [This document](http://www.ipgeoblock.com/codex/what-should-i-do-when-i-m-locked-out.html "What should I do when I'm locked out? | IP Geo Block")
345
+ can also help you.
346
+
347
+ = How to resolve "Sorry, your request cannot be accepted."? =
348
+
349
+ If you encounter this message, please refer to
350
+ [this document](http://www.ipgeoblock.com/codex/you-are-not-allowed-to-access.html "Why &ldquo;You are not allowed to access this page&rdquo; ? | IP Geo Block")
351
+ to resolve your blocking issue.
352
+
353
+ = Some admin function doesn't work. How to solve it? =
354
+
355
+ This could be happened because of the same reason as the previous FAQ. Please
356
+ follow the steps in
357
+ [this document](http://www.ipgeoblock.com/codex/you-are-not-allowed-to-access.html "Why &ldquo;You are not allowed to access this page&rdquo; ? | IP Geo Block").
358
+
359
+ If you can't solve your issue, please let me know about it on the
360
+ [support forum](https://wordpress.org/support/plugin/ip-geo-block/ "View: Plugin Support &laquo; WordPress.org Forums").
361
+ Your logs in this plugin and "**Installation information**" at "**Plugin
362
+ settings**" will be a great help to resolve the issue.
363
+
364
+ = How can I fix "Unable to write" error? =
365
+
366
+ When you enable "**Force to load WP core**" options, this plugin will try to
367
+ configure `.htaccess` in your `/wp-content/plugins/` and `/wp-content/themes/`
368
+ directory in order to protect your site against the malicous attacks to the
369
+ [OMG plugins and shemes](http://www.ipgeoblock.com/article/exposure-of-wp-config-php.html "Prevent exposure of wp-config.php | IP Geo Block").
370
+
371
+ But some servers doesn't give reading / writing permission against `.htaccess`
372
+ to WordPress. In this case, you can configure these `.htaccess` files by your
373
+ own hand instead of enabling "**Force to load WP core**" options.
374
+
375
+ Please refer to
376
+ "[How can I fix permission troubles?](http://www.ipgeoblock.com/codex/how-can-i-fix-permission-troubles.html 'How can I fix permission troubles? | IP Geo Block')"
377
+ in order to fix this error.
378
+
379
+ = Does this plugin works well with caching? =
380
+
381
+ For the back-end protection, the answer is YES if you disable caching on
382
+ back-end. But for the front-end, the answer depends on the caching method
383
+ you are employing.
384
+
385
+ Currently, the following cache plugins and configurations can be supported:
386
+
387
+ - [WP Super Cache](https://wordpress.org/plugins/wp-super-cache/ "WP Super Cache &mdash; WordPress Plugins")
388
+ Select "**Use PHP to serve cache files**" and enable "**Late init**".
389
+
390
+ - [W3 Total Cache](https://wordpress.org/plugins/w3-total-cache/ "W3 Total Cache &mdash; WordPress Plugins")
391
+ Select "**Disk: Basic**" and enable "**Late initialization**" for page cache.
392
+ "**Disk: Enhanced**" (where "**Late initialization**" is not available) in
393
+ W3TC 0.9.5.1 seems to work good without any imcompatibility with this plugin.
394
+
395
+ - [Vendi Cache](https://wordpress.org/plugins/vendi-cache/ "Vendi Cache &mdash; WordPress Plugins")
396
+ This was formerly built in Wordfence. Select "**basic caching**" for
397
+ Vendi Cache and **"mu-plugin" (ip-geo-block-mu.php)** for IP Geo Block.
398
+
399
+ If your plugin serves page caching by `mod_rewrite` via `.htaccess`
400
+ (e.g. WP Fastest Cache) or caching by `advanced-cache.php` drop-in
401
+ (e.g. Comet Cache) or your hosting provider serves page caching at
402
+ server side, "**Blocking on front-end**" might lead to generate
403
+ inconsistent pages.
404
+
405
+ For more details, please refer to some documents at
406
+ "[Blocking on front-end](http://www.ipgeoblock.com/codex/#blocking-on-front-end 'Codex | IP Geo Block')".
407
+
408
+ = How can I test this plugin works? =
409
+
410
+ The easiest way is to use
411
+ [free proxy browser addon](https://www.google.com/search?q=free+proxy+browser+addon "free proxy browser addon - Google Search").
412
+ Another one is to use
413
+ [http header browser addon](https://www.google.com/search?q=browser+add+on+modify+http+header "browser add on modify http header - Google Search").
414
+ You can add an IP address to the `X-Forwarded-For` header to emulate the
415
+ access behind the proxy. In this case, you should add `HTTP_X_FORWARDED_FOR`
416
+ into the "**$_SERVER keys for extra IPs**" on "**Settings**" tab.
417
+
418
+ See more details at
419
+ "[How to test prevention of attacks](http://www.ipgeoblock.com/codex/#how-to-test-prevention-of-attacks 'Codex | IP Geo Block')".
420
+
421
+ = Do I have to turn on all the selection to enhance security? =
422
+
423
+ Yes. Roughly speaking, the strategy of this plugin has been constructed as
424
+ follows:
425
+
426
+ - **Block by country**
427
+ It blocks malicious requests from outside your country.
428
+
429
+ - **Prevent Zero-day Exploit**
430
+ It blocks malicious requests from your country.
431
+
432
+ - **Force to load WP core**
433
+ It blocks the request which has not been covered in the above two.
434
+
435
+ - **Bad signatures in query**
436
+ It blocks the request which has not been covered in the above three.
437
+
438
+ Please try "**Best settings**" button at the bottom of this plugin's setting
439
+ page for easy setup. And also see more details in
440
+ "[The best practice of target settings](http://www.ipgeoblock.com/codex/the-best-practice-for-target-settings.html 'The best practice of target settings | IP Geo Block')".
441
+
442
+ = Does this plugin validate all the requests? =
443
+
444
+ Unfortunately, no. This plugin can't handle the requests that are not
445
+ parsed by WordPress. In other words, a standalone file (PHP, CGI or
446
+ something excutable) that is unrelated to WordPress can't be validated
447
+ by this plugin even if it is in the WordPress install directory.
448
+
449
+ But there're exceptions: When you enable "**Force to load WP core**" for
450
+ **Plugins area** or **Themes area**, a standalone PHP file becomes to be
451
+ able to be blocked. Sometimes this kind of file has some vulnerabilities.
452
+ This function protects your site against such a case.
453
+
454
+ == Other Notes ==
455
+
456
+ = Known issues =
457
+
458
+ * No image is shown after drag & drop a image in grid view at "Media Library".
459
+ For more details, please refer to
460
+ [this ticket at Github](https://github.com/tokkonopapa/WordPress-IP-Geo-Block/issues/2 "No image is shown after drag & drop a image in grid view at "Media Library". - Issue #2 - tokkonopapa/WordPress-IP-Geo-Block - GitHub").
461
+
462
+ * From [WordPress 4.5](https://make.wordpress.org/core/2016/03/09/comment-changes-in-wordpress-4-5/ "Comment Changes in WordPress 4.5 &#8211; Make WordPress Core"),
463
+ `rel=nofollow` attribute and value pair had no longer be added to relative
464
+ or same domain links within `comment_content`. This change prevents to block
465
+ "Server Side Request Forgeries" (not Cross Site but a malicious link in the
466
+ comment field of own site).
467
+
468
+ == Screenshots ==
469
+
470
+ 1. **IP Geo Plugin** - Settings.
471
+ 2. **IP Geo Plugin** - Statistics.
472
+ 3. **IP Geo Plugin** - Logs.
473
+ 4. **IP Geo Plugin** - Search.
474
+ 5. **IP Geo Plugin** - Attribution.
475
+
476
+ == Changelog ==
477
+
478
+ = 3.0.1.2 =
479
+ * **Bug fix:** Fix the blocking issue in some environments when upgrading from
480
+ 2.2.9.1 to 3.0.0.
481
+ * **Bug fix:** Fix the blocking issue at opening a new window via context menu
482
+ on dashboard.
483
+ * **Bug fix:** Fix the potential issue of 500 Internal error in cron job.
484
+ * **Improvement:** Revive 410 Gone for response code.
485
+ * **Improvement:** Prevent the issue of resetting matching rule and country
486
+ code at upgrading.
487
+
488
+ = 3.0.1.1 =
489
+ * **Bug fix:** Fix the issue where **Login form** could not be disabled on
490
+ **Back-end target settings**.
491
+ * **Bug fix:** Fix the issue where trackback and pingback could not be blocked
492
+ since 2.2.4.
493
+ * **Improved:** Apply the action hook 'pre_trackback_post' that was introduced
494
+ in WP 4.7.0.
495
+ * **Improved:** Use 'safe_redirect()' instead of 'redirect()' for secured
496
+ internal redirection. If you set an external url for **Redirect URL**, please
497
+ use the filter hook 'allowed_redirect_hosts'.
498
+ * **Improved:** Better compatibility with the plugin "Anti-Malware Security
499
+ and Brute-Force Firewall".
500
+
501
+ = 3.0.1 =
502
+ * **Bug fix:** Add lock mechanism for local geolocation DBs to avoid potential
503
+ fatal error.
504
+ * **Improvement:** Add self blocking prevention potentially caused by login
505
+ attempts with the same IP address of logged in user.
506
+ * **New feature:** Add "**Installation information**" button to make it easy
507
+ to submit an issue at support forum.
508
+
509
+ = 3.0.0 =
510
+ * **New feature:** Add the function of blocking on front-end.
511
+ * **New filter hook:** Add `ip-geo-block-public` to extend validation on
512
+ front-end.
513
+ * **Improvement:** Avoid conflict with "Open external links in a new window"
514
+ plugin and some other reason to prevent duplicated window open. For more
515
+ detail, see
516
+ [this discussion at support forum](https://wordpress.org/support/topic/ip-geoblock-opens-2-windows-on-link-clicks-when-user-is-logged-in/ "Topic: IP Geoblock opens 2 windows on link clicks when user is logged in &laquo; WordPress.org Forums").
517
+ * **Improvement:** Better compatibility with some plugins, themes and widgets.
518
+ * **Improvement:** Deferred execution of SQL command to improve the response.
519
+ * **Improvement:** Make the response compatible with WP original when it is
520
+ requested by GET method.
521
+ * See some details at
522
+ [release 3.0.0](http://www.ipgeoblock.com/changelog/release-3.0.0.html "3.0.0 Release Note | IP Geo Block").
523
+
524
+ = 2.2.9.1 =
525
+ * **Bug fix:** Blocking Wordfence scanning.
526
+ ([@](https://wordpress.org/support/topic/wordfence-conflict-2/ "WordFence Conflict"))
527
+ * **Bug fix:** Illegal elimination of colon in text field for IP address.
528
+ ([@](https://wordpress.org/support/topic/adding-ipv6-to-white-list/ "Adding IPv6 to white list"))
529
+ * **Improved:** Compatibility with PHP 7 that cause to feel relaxed.
530
+ ([@](https://wordpress.org/support/topic/plans-for-php-7-compatiblity/ "Plans for PHP 7 compatiblity?"))
531
+ * **Improved:** Avoid resetting whitelist on update by InfiniteWP.
532
+ ([@](https://wordpress.org/support/topic/whitelist-resets-on-update/ "[Resolved] Whitelist resets on update"))
533
+ * **Trial feature:** `X-Robots-Tag` HTTP header with `noindex, nofollow`
534
+ for login page.
535
+ ([@](https://wordpress.org/support/topic/ip-geo-block-and-searchmachines/ "IP GEo-block and searchmachines"))
536
+
537
+ = 2.2.9 =
538
+ * **New feature:** A new option that makes this plugin configured as a
539
+ "Must-use plugin". It can massively reduce the server load especially
540
+ against brute-force attacks because it initiates this plugin prior to
541
+ other typical plugins.
542
+ * **Improvement:** Validation of a certain signature against XSS is internally
543
+ added to "Bad signature in query" by default.
544
+ * **Improvement:** Improved compatibility with PHP 7
545
+ (Thanks to [FireMyst](https://wordpress.org/support/topic/plans-for-php-7-compatiblity/ "Topic: Plans for PHP 7 compatiblity? &laquo; WordPress.org Forums").
546
+ * Find details in [2.2.9 Release Note](http://www.ipgeoblock.com/changelog/release-2.2.9.html "2.2.9 Release Note").
547
+
548
+ = 2.2.8.2 =
549
+ * **Bug fix:** Fixed the mismatched internal version number.
550
+
551
+ = 2.2.8.1 =
552
+ * **Bug fix:** Fixed the issue of undefined function `wp_get_raw_referer()`
553
+ error that happened under certain condition. See
554
+ [the issue](https://wordpress.org/support/topic/since-php-update-fatal-error-everytime-i-want-to-edit-a-post/ "Since PHP update Fatal error everytime I want to edit a post")
555
+ at forum.
556
+ * **Improved:** Avoid resetting country code on update. See
557
+ [the issue](https://wordpress.org/support/topic/whitelist-resets-on-update/ "Whitelist resets on update")
558
+ at forum.
559
+
560
+ = 2.2.8 =
561
+ * **Bug fix:** Fixed the issue of stripping some required characters for Google
562
+ maps API key.
563
+ * **New feature:** Whois database Lookup for IP address on search tab.
564
+ * **Update:** Updated geolocation API libraries and services.
565
+ * Find more details in [2.2.8 Release Note](http://www.ipgeoblock.com/changelog/release-2.2.8.html "2.2.8 Release Note").
566
+
567
+ = 2.2.7 =
568
+ * **Bug fix:** Fix inadequate validation of "**Bad signatures in query**".
569
+ * **Improvement:** Add fallback for Google Maps API key
570
+ ([@](https://wordpress.org/support/topic/226-problem-with-search-resp-google-maps "WordPress &#8250; Support &raquo; [2.2.6] Problem with SEARCH resp. Google Maps"))
571
+ and corruption of "Bad signatures"
572
+ ([@](https://wordpress.org/support/topic/226-problem-with-bad-signatures-in-query "WordPress &#8250; Support &raquo; [2.2.6] Problem with &quot;Bad signatures in query&quot;")).
573
+ * **Update:** Update geolocation service api.
574
+ * Find details about Google Maps API in [2.2.7 Release Note](http://www.ipgeoblock.com/changelog/release-2.2.7.html "2.2.7 Release Note").
575
+
576
+ = 2.2.6 =
577
+ * **New feature:** Add saving csv file of logs in "Logs" tab.
578
+ * **New feature:** Add filter hook `ip-geo-block-record-log` to control over
579
+ the conditions of recording in more detail.
580
+ * **Bug fix:** Fixed the issue that "Exceptions" for Plugins/Themes area does
581
+ not work properly. Please confirm your settings again.
582
+ * See details at [release 2.2.6](http://www.ipgeoblock.com/changelog/release-2.2.6.html "2.2.6 Release Note").
583
+
584
+ = 2.2.5 =
585
+ * **New feature:** On the settings page, you can specify the pliugin or theme
586
+ which would cause undesired blocking in order to exclude it from the
587
+ validation target without embedding any codes into `functions.php`.
588
+ * **Improvement:** Optimize resource loading on admin dashboard.
589
+ * **Improvement:** Support clean uninstall for network / multisite.
590
+ * **Improvement:** Improve the compatibility of downloading IP address
591
+ databases for Microsoft IIS.
592
+ * **Bug fix:** Support `FORCE_SSL_ADMIN`.
593
+ * **Bug fix:** Fix the issue of
594
+ [@](https://wordpress.org/support/topic/compatibility-with-ag-custom-admin "WordPress › Support » Compatibility with AG Custom Admin")
595
+ and change the option name
596
+ "**Important files**" to "**Bad signatures in query**" to avoid misuse.
597
+ * **Bug fix:** Fix the issue of
598
+ [@](https://wordpress.org/support/topic/gb-added-to-whitelist "WordPress › Support » GB added to whitelist")
599
+ which might be caused by some race condition.
600
+ * **Bug fix:** Fix the issue of restoring post revisions which was blocked.
601
+
602
+ = 2.2.4.1 =
603
+ Sorry for frequent updating.
604
+
605
+ * **Bug fix:** Fixed the issue of `Warning: strpos(): Empty needle in...` that
606
+ was reported in
607
+ [@](https://wordpress.org/support/topic/version-224-produces-warning-message "WordPress › Support » Version 2.2.4 Produces Warning Message")
608
+ and
609
+ [@](https://wordpress.org/support/topic/error-after-update-to-newest-version "WordPress › Support » Error after Update to newest version").
610
+
611
+ = 2.2.4 =
612
+ * **Bug fix:** Fixed the issue that some links on network admin of multisite
613
+ were blocked when WP-ZEP for `admin area` or `admin ajax/post` was enabled.
614
+ * **New feature:** Added configure of `.htaccess` for the plugins/themes area.
615
+ * **Enhancement:** Added `wp-signup.php` to the list of validation target.
616
+ * **Enhancement:** Added exporting and importing the setting parameters.
617
+ * **Improvement:** Made the logout url compatible with
618
+ [Rename wp-login.php](https://wordpress.org/plugins/rename-wp-login/).
619
+ * **Improvement:** Made condition of validation more strictly at admin
620
+ diagnosis to prevent unnecessary notice of self blocking.
621
+ ([@](https://wordpress.org/support/topic/youll-be-blocked-after-you-log-out-notice-doesnt-disappear "[resolved] &quot;You'll be blocked after you log out&quot; notice doesn't disappear"))
622
+ * **Improvement:** Improved some of UI.
623
+ ([@](https://wordpress.org/support/topic/possible-to-select-which-countries-are-blocked "[resolved] Possible to select which countries are blocked?"),
624
+ [@](https://wordpress.org/support/topic/ip-geo-block-black-list "IP Geo Block Black List"))
625
+ * See some details at [release 2.2.4](http://www.ipgeoblock.com/changelog/release-2.2.4.html "2.2.4 Release Note").
626
+
627
+ = 2.2.3.1 =
628
+ * **Bug fix:** Fixed the issue that disabled validation target was still
629
+ blocked by country.
630
+ ([@](https://wordpress.org/support/topic/logs-whitelist-comments-still-blocked "[resolved] logs whitelist comments still blocked?"))
631
+ * **Improvement:** Better handling of charset and errors for MySQL.
632
+ ([@](https://wordpress.org/support/topic/whitelist-log "[resolved] Whitelist + Log"))
633
+
634
+ = 2.2.3 =
635
+ * **Improvement:** Since WordPress 4.4, XML-RPC system.multicall is disabled
636
+ when the authentication fails, but still processed all the methods to the
637
+ end. Now this plugin immediately blocks the request when the authentication
638
+ fails without processing the rest of the methods.
639
+ * **Improvement:** Add UI to change the maximum number of login attempts.
640
+ * **Improvement:** Add a fallback process of setting up the directory where
641
+ the geo location database APIs should be installed. It will be set as
642
+ `wp-content/uploads/` instead of `wp-content/plugins/ip-geo-block/` or
643
+ `wp-content/` in case of being unable to obtain proper permission.
644
+ ([@](https://wordpress.org/support/topic/deactivated-after-updte-why "[resolved] Deactivated after update - why?"),
645
+ [@](https://wordpress.org/support/topic/the-plugin-caused-an-error-message "[resolved] The plugin caused an error message"))
646
+ * **Improvement:** Moderate the conditions of redirection after logout.
647
+ ([@](https://wordpress.org/support/topic/logout-redirect-doesnt-work-when-plugin-is-active "[resolved] Logout redirect doesn't work when plugin is active"))
648
+ * **Improvement:** Prevent self blocking caused by irrelevant signature.
649
+ ([@](https://wordpress.org/support/topic/works-too-well-blocked-my-wp-admin-myself "[resolved] Works too well - Blocked my wp-admin myself"))
650
+ * **Bug fix:** Fixed the issue of conflicting with certain plugins due to the
651
+ irrelevant handling of js event.
652
+ ([@](https://wordpress.org/support/topic/cannot-edit-pages-when-ip-geo-block-is-enabled "[resolved] Cannot edit pages when ip-geo-block is enabled."))
653
+ * **New feature:** Add "Blocked per day" graph for the daily statistics.
654
+ * See some details at [2.2.3 release note](http://www.ipgeoblock.com/changelog/release-2.2.3.html "2.2.3 Release Note").
655
+
656
+ = 2.2.2.3 =
657
+ Sorry for frequent update again but the following obvious bugs should be fixed.
658
+
659
+ * **Bug fix:** Fixed the issue of not initializing country code at activation.
660
+ * **Bug fix:** Fixed the issue that scheme less notation like '//example.com'
661
+ could not be handled correctly.
662
+
663
+ = 2.2.2.2 =
664
+ Sorry for frequent update.
665
+
666
+ * **Bug fix:** Fixed the issue of race condition at activation. This fix is
667
+ related to the urgent security update at **2.2.2.1 which was not actually
668
+ the security issue but a bug**.
669
+ See [this thread](https://wordpress.org/support/topic/white-list-hack "white list hack")
670
+ about little more details.
671
+ * **Improvement:** Improved the compatibility with Jetpack.
672
+
673
+ = 2.2.2.1 =
674
+ * **Urgent security update:** Killed the possibility of the options being
675
+ altered.
676
+
677
+ = 2.2.2 =
678
+ * **Enhancement:** Refactored some codes and components. The number of attacks
679
+ that can be proccessed per second has been improved by 25% at the maximum.
680
+ * **Improvement:** In the previous version, the statistical data was recorded
681
+ into `wp_options`. It caused the uncertainty of recording especially in case
682
+ of burst attacks. Now the data will be recorded in an independent table to
683
+ improve this issue.
684
+ * **Bug fix:** Fixed conflict with NextGEN Gallary Pro.
685
+ Thanks to [bodowewer](https://wordpress.org/support/profile/bodowewer).
686
+ * **Bug fix:** Fixed some filter hooks that did not work as intended.
687
+ * See more details at [2.2.2 release note](http://www.ipgeoblock.com/changelog/release-2.2.2.html "2.2.2 Release Note").
688
+
689
+ = 2.2.1.1 =
690
+ * **Bug fix:** Fixed "open_basedir restriction" issue caused by `file_exists()`.
691
+
692
+ = 2.2.1 =
693
+ * **Enhancement:** In previous version, local geolocation databases will always
694
+ be removed and downloaded again at every upgrading. Now, the class library
695
+ for Maxmind and IP2Location have become independent of this plugin and you
696
+ can put them outside this plugin in order to cut the above useless process.
697
+ The library can be available from
698
+ [WordPress-IP-Geo-API](https://github.com/tokkonopapa/WordPress-IP-Geo-API).
699
+ * **Deprecated:** Cooperation with IP2Location plugins such as
700
+ [IP2Location Tags](http://wordpress.org/plugins/ip2location-tags/ "WordPress - IP2Location Tags - WordPress Plugins"),
701
+ [IP2Location Variables](http://wordpress.org/plugins/ip2location-variables/ "WordPress - IP2Location Variables - WordPress Plugins"),
702
+ [IP2Location Country Blocker](http://wordpress.org/plugins/ip2location-country-blocker/ "WordPress - IP2Location Country Blocker - WordPress Plugins")
703
+ is out of use. Instead of it, free [IP2Location LITE databases for IPv4 and
704
+ IPv6](http://lite.ip2location.com/ "Free IP Geolocation Database") will be
705
+ downloaded.
706
+ * **Improvement:** Improved connectivity with Jetpack.
707
+ * **Improvement:** Improved immediacy of downloading databases at upgrading.
708
+ * **Improvement:** Replaced a terminated RESTful API service with a new stuff.
709
+ * **Bug fix:** Fixed issue that clicking a link tag without href always
710
+ refreshed the page. Thanks to
711
+ [wyclef](https://wordpress.org/support/topic/conflict-with-menu-editor-plugin "WordPress › Support » Conflict with Menu Editor plugin?").
712
+ * **Bug fix:** Fixed issue that deactivating and activating repeatedly caused
713
+ to show the welcome message.
714
+ * **Bug fix:** Fixed issue that a misaligned argument in the function caused
715
+ 500 internal server error when a request to the php files in plugins/themes
716
+ area was rewrited to `rewrite.php`.
717
+
718
+ = 2.2.0.1 =
719
+ Sorry for frequent update.
720
+
721
+ * **Fix:** Fixed the issue that some actions of other plugins were blocked.
722
+
723
+ = 2.2.0 =
724
+ * **Important:** Now **Block by country** and **Prevent Zero-day Exploit**
725
+ become to work independently on **Admin area**, **Admin ajax/post** at
726
+ **Validation target settings**. Please reconfirm them.
727
+ * **Important:** Previously, a request whose country code can't be available
728
+ was always blocked. But from this release, such a request is considered as
729
+ comming from the country whose code is `ZZ`. It means that you can put `ZZ`
730
+ into the white list and black list.
731
+ * **New feature:** White list and Black list of extra IP addresses prior to
732
+ the validation of country code. Thanks to Fabiano for good suggestions at
733
+ [support forum](https://wordpress.org/support/topic/white-list-of-ip-addresses-or-ranges "WordPress › Support » White list of IP addresses or ranges?")
734
+ * **New feature:** Malicious signatures to prevent disclosing the important
735
+ files via vulnerable plugins or themes. A malicious request to try to expose
736
+ `wp-config.php` or `passwd` can be blocked.
737
+ * **New feature:** Add privacy considerations related to IP address. Add
738
+ **Anonymize IP address** at **Record settings**.
739
+ * **Bug fix:** Fix the issue that spaces in **Text message on comment form**
740
+ are deleted.
741
+ * See details at [2.2.0 release note](http://www.ipgeoblock.com/changelog/release-2.2.0.html "2.2.0 Release Note").
742
+
743
+ = 2.1.5.1 =
744
+ * **Bug fix:** Fixed the issue that the Blacklist did not work properly. Thanks
745
+ to TJayYay for reporting this issue at
746
+ [support forum](https://wordpress.org/support/topic/hackers-from-country-in-blocked-list-of-countries-trying-to-login "WordPress › Support » Hackers from country in Blocked List of Countries trying to login").
747
+
748
+ = 2.1.5 =
749
+ * **Enhancement:** Enforce preventing self blocking at the first installation.
750
+ And add the scan button to get all the country code using selected API.
751
+ Thanks to **Nils** for a nice idea at
752
+ [support forum](https://wordpress.org/support/topic/locked-out-due-to-eu-vs-country "WordPress › Support » Locked out due to EU vs. Country").
753
+ * **New feature:** Add pie chart to display statistics of "Blocked by country".
754
+ * **Enhancement:** WP-ZEP is reinforced against CSRF.
755
+ * **Bug fix:** Fix illegal handling of the fragment in a link.
756
+ * See details at [2.1.5 release note](http://www.ipgeoblock.com/changelog/release-2.1.5.html "2.1.5 Release Note").
757
+
758
+ = 2.1.4 =
759
+ * **Bug fix:** Fix the issue that this plugin broke functionality of a certain
760
+ plugin. Thanks to **opsec** for reporting this issue at
761
+ [support forum](https://wordpress.org/support/topic/blocks-saves-in-types-or-any-plugins-from-wp-typescom "WordPress › Support » Blocks saves in Types or any plugins from wp-types.com").
762
+ * **Improvement:** Add checking process for validation rule to prevent being
763
+ blocked itself. Thanks to **internationals** for proposing at
764
+ [support forum](https://wordpress.org/support/topic/locked-out-due-to-eu-vs-country "WordPress › Support » Locked out due to EU vs. Country")
765
+ * **Improvement:** Arrage the order of setting sections to focus the goal of
766
+ this plugin.
767
+ * See details at [2.1.4 release note](http://www.ipgeoblock.com/changelog/release-2.1.4.html "2.1.4 Release Note").
768
+
769
+ = 2.1.3 =
770
+ * **New feature:** Add "show" / "hide" at each section on the "Settings" tab.
771
+ * **New feature:** Add an emergency function that invalidate blocking behavior
772
+ in case yourself is locked out. This feature is commented out by default at
773
+ the bottom of `ip-geo-block.php`.
774
+ * **Improvement:** Prevent adding query strings to the static resources when
775
+ users logged in.
776
+ * **Improvement:** Improved the compatibility with Autoptimize.
777
+ * **Bug fix:** Fix the issue related to showing featured themes on dashboard.
778
+ * **Bug fix:** Fix minor bug in `rewrite.php` for the advanced use case.
779
+ * See details at [2.1.3 release note](http://www.ipgeoblock.com/changelog/release-2.1.3.html "2.1.3 Release Note").
780
+
781
+ = 2.1.2 =
782
+ This is a maintenance release.
783
+
784
+ * **Bug fix:** Fix the issue that the login-fail-counter didn't work when the
785
+ validation at `Login form` was `block by country (register, lost password)`.
786
+ In this release, the login-fail-counter works correctly.
787
+ * **Bug fix:** Fix the issue that the validation settings of `Admin area` and
788
+ `Admin ajax/post` were influential with each other. Now each of those works
789
+ individually.
790
+ * **Bug fix:** "Site Stats" of Jetpack is now shown on the admin bar which
791
+ issue was reported on [support forum](https://wordpress.org/support/topic/admin-area-prevent-zero-day-exploit-incompatible-with-jetpack-site-stats-in-a "WordPress › Support » Admin area - Prevent zero-day exploit: Incompatible with Jetpack Site Stats in A").
792
+ * **Improvement:** Hide checking the existence of log db behind the symbol
793
+ `IP_GEO_BLOCK_DEBUG` to reduce 1 query on admin screen.
794
+ * **Improvement:** Add alternative functions of BCMath extension to avoid
795
+ `PHP Fatal error: Call to undefined function` in `IP2Location.php` when
796
+ IPv6 is specified.
797
+ * **Improvement:** Use MaxMind database at the activating process not to be
798
+ locked out by means of inconsistency of database at the activation and after.
799
+ * See more details at [2.1.2 release note](http://www.ipgeoblock.com/changelog/release-2.1.2.html "2.1.2 Release Note").
800
+
801
+ = 2.1.1 =
802
+ * **New feature:** Added `Block by country (register, lost password)` at
803
+ `Login form` on `Settings` tab in order to accept the registered users as
804
+ membership from anywhere but block the request of new user ragistration and
805
+ lost password by the country code. Is't suitable for BuddyPress and bbPress.
806
+ * **Improvement:** Added showing the custom error page for http response code
807
+ 4xx and 5xx. For example the `403.php` in the theme template directory or in
808
+ the child theme directory is used if it exists. And new filter hooks
809
+ `ip-geo-block-(comment|xmlrpc|login|admin)-(status|reason)` are available
810
+ to customize the response code and reason for human.
811
+ * **Obsoleted:** Obsoleted the filter hooks
812
+ `ip-geo-block-(admin-actions|admin-pages|wp-content)`. Alternatively new
813
+ filter hooks `ip-geo-block-bypass-(admins|plugins|themes)` are added to
814
+ bypass WP-ZEP.
815
+ * Find out more details in the [2.1.1 release note](http://www.ipgeoblock.com/changelog/release-2.1.1.html "2.1.1 Release Note").
816
+
817
+ = 2.1.0 =
818
+ * **New feature:** Expanded the operating range of ZP-ZEP, that includes admin
819
+ area, plugins area, themes area. Now it can prevent a direct malicios attack
820
+ to the file in plugins and themes area. Please go to the "Validation Settings"
821
+ on "Settings" tab and check it. Also check my article in
822
+ "[Analysis of Attack Vector against WP Plugins](http://www.ipgeoblock.com/article/analysis-attack-vector.html)".
823
+ * **Bug fix:** Fixed the issue that action hook `ip-geo-block-backup-dir` did
824
+ not work correctly because the order of argument was mismatched.
825
+ * **Bug fix:** Fixed the issue that a record including utf8 4 bytes character
826
+ in its columns was not logged into DB in WordPress 4.2.
827
+ * **Improvement:** Fixed the issue that Referrer Suppressor do nothing with a
828
+ new element which is added into DOM after DOM ready. The event handler is
829
+ now delegated at the `body`.
830
+
831
+ = 2.0.8 =
832
+ * Fixed an issue that a certain type of attack vector to the admin area (
833
+ [example](https://blog.sucuri.net/2014/08/database-takeover-in-custom-contact-forms.html "Critical Vulnerability Disclosed on WordPress Custom Contact Forms Plugin")
834
+ ) could not be blocked by the reason that some plugins accept it on earlier
835
+ hook (ie `init`) than this plugin (previously `admin_init`).
836
+ * Added re-creating DB table for validation logs in case of accidentally
837
+ failed at activation process.
838
+ * The time of day is shown with local time by adding GMT offset based on
839
+ the time zone setting.
840
+ * Optimized resource loading and settings to avoid redundancy.
841
+ * See details at [this plugin's blog](http://www.ipgeoblock.com/changelog/release-2.0.8.html "2.0.8 Release Note").
842
+
843
+ = 2.0.7 =
844
+ * Avoid JavaScript error which occurs if an anchor link has no `href`.
845
+ * Improved UI on admin screen.
846
+ * Added a diagnosis for creation of database table.
847
+
848
+ = 2.0.6 =
849
+ * Sorry for urgent update but avoid an javascript error.
850
+
851
+ = 2.0.4 =
852
+ * Sorry for frequent update but added a function of showing admin notice
853
+ when none of the IP geolocation providers is selected. Because the user
854
+ will be locked out from admin screen when the cache expires.
855
+ * **Bug fix:** Fixed an issue of `get_geolocation()` method at a time of
856
+ when the cache of IP address is cleared.
857
+ * Referrer suppressor now supports [meta referrer](https://wiki.whatwg.org/wiki/Meta_referrer "Meta referrer - WHATWG Wiki")
858
+
859
+ = 2.0.3 =
860
+ * **Bug fix:** Fixed an issue that empty black list doesn't work correctly
861
+ when matching rule is black list.
862
+ * **New feature:** Added 'Zero-day Exploit Prevention for wp-admin'.
863
+ Because it is an experimental feature, please open a new issue at
864
+ [support forum](https://wordpress.org/support/plugin/ip-geo-block "WordPress &#8250; Support &raquo; IP Geo Block")
865
+ if you have any troubles with it.
866
+ * **New feature:** Referrer suppressor for external link. When you click an
867
+ external hyperlink on admin screen, http referrer will be suppressed to
868
+ hide a footprint of your site.
869
+ * Also added the filter hook `ip-geo-block-admin-actions` for safe actions
870
+ on back-end.
871
+
872
+ = 2.0.2 =
873
+ * **New feature:** Include `wp-admin/admin-post.php` as a validation target
874
+ in the `Admin area`. This feature is to protect against a vulnerability
875
+ such as
876
+ [Analysis of the Fancybox-For-WordPress Vulnerability](http://blog.sucuri.net/2015/02/analysis-of-the-fancybox-for-wordpress-vulnerability.html)
877
+ on Sucuri Blog.
878
+ * Added a sample code snippet as a use case for 'Give ajax permission in
879
+ case of safe actions on front facing page'. See Example 10 in `sample.php`.
880
+
881
+ = 2.0.1 =
882
+ * Fixed the issue of improper scheme from the HTTPS site when loading js
883
+ for google map.
884
+ * In order to prevent accidental disclosure of the length of password,
885
+ changed the length of `*` (masked password) which is logged into the
886
+ database.
887
+
888
+ = 2.0.0 =
889
+ * **New feature:** Protection against brute-force and reverse-brute-force
890
+ attacks to `wp-login.php`, `xmlrpc.php` and admin area.
891
+ This is an experimental function and can be enabled on `Settings` tab.
892
+ Malicious access can try to login only 5 times per IP address. This retry
893
+ counter can be reset to zero by `Clear statistics` on `Statistics` tab.
894
+
895
+ = 1.0.0 =
896
+ * Ready to release.
897
+
898
+ == Upgrade Notice ==
admin/class-ip-geo-block-admin.php ADDED
@@ -0,0 +1,982 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IP Geo Block - Admin class
4
+ *
5
+ * @package IP_Geo_Block
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2016 tokkonopapa
10
+ */
11
+
12
+ class IP_Geo_Block_Admin {
13
+
14
+ /**
15
+ * Instance of this class.
16
+ *
17
+ */
18
+ protected static $instance = null;
19
+
20
+ /**
21
+ * Tab of the admin page.
22
+ *
23
+ */
24
+ private $admin_tab = 0;
25
+
26
+ /**
27
+ * Initialize the plugin by loading admin scripts & styles
28
+ * and adding a settings page and menu.
29
+ */
30
+ private function __construct() {
31
+ // Load plugin text domain.
32
+ add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
33
+
34
+ // Setup a nonce to validate authentication.
35
+ add_filter( 'wp_redirect', array( $this, 'add_admin_nonce' ), 10, 2 );
36
+
37
+ // Add the options page and menu item.
38
+ add_action( 'admin_menu', array( $this, 'setup_admin_page' ) );
39
+ add_action( 'wp_ajax_ip_geo_block', array( $this, 'admin_ajax_callback' ) );
40
+ add_action( 'admin_post_ip_geo_block', array( $this, 'admin_ajax_callback' ) );
41
+ add_filter( 'wp_prepare_revision_for_js', array( $this, 'add_revision_nonce' ), 10, 3 );
42
+
43
+ // If multisite, then enque the authentication script for network admin
44
+ if ( is_multisite() ) {
45
+ add_action( 'network_admin_menu', 'IP_Geo_Block::enqueue_nonce' );
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Return an instance of this class.
51
+ *
52
+ */
53
+ public static function get_instance() {
54
+ return self::$instance ? self::$instance : ( self::$instance = new self );
55
+ }
56
+
57
+ /**
58
+ * Load the plugin text domain for translation.
59
+ *
60
+ */
61
+ public function load_plugin_textdomain() {
62
+ load_plugin_textdomain( IP_Geo_Block::PLUGIN_NAME, FALSE, dirname( IP_GEO_BLOCK_BASE ) . '/languages/' );
63
+ }
64
+
65
+ /**
66
+ * Add nonce when redirect into wp-admin area.
67
+ *
68
+ */
69
+ public function add_admin_nonce( $location, $status ) {
70
+ return IP_Geo_Block_Util::rebuild_nonce( $location, $status );
71
+ }
72
+
73
+ /**
74
+ * Get the action name of ajax for nonce
75
+ *
76
+ */
77
+ private function get_ajax_action() {
78
+ return IP_Geo_Block::PLUGIN_NAME . '-ajax-action';
79
+ }
80
+
81
+ /**
82
+ * Register and enqueue plugin-specific style sheet and JavaScript.
83
+ *
84
+ */
85
+ public function enqueue_admin_assets() {
86
+ $footer = TRUE;
87
+ $dependency = array( 'jquery' );
88
+
89
+ // css for option page
90
+ wp_enqueue_style( IP_Geo_Block::PLUGIN_NAME . '-admin-styles',
91
+ plugins_url( ! defined( 'IP_GEO_BLOCK_DEBUG' ) || ! IP_GEO_BLOCK_DEBUG ?
92
+ 'css/admin.min.css' : 'css/admin.css', __FILE__
93
+ ),
94
+ array(), IP_Geo_Block::VERSION
95
+ );
96
+
97
+ switch ( $this->admin_tab ) {
98
+ case 1:
99
+ // js for google chart
100
+ wp_register_script(
101
+ $addon = IP_Geo_Block::PLUGIN_NAME . '-google-chart',
102
+ 'https://www.google.com/jsapi', array(), NULL, $footer
103
+ );
104
+ wp_enqueue_script( $addon );
105
+ break;
106
+
107
+ case 2:
108
+ // js for google map
109
+ $settings = IP_Geo_Block::get_option();
110
+ if ( $key = $settings['api_key']['GoogleMap'] ) {
111
+ wp_enqueue_script( IP_Geo_Block::PLUGIN_NAME . '-gmap-js',
112
+ plugins_url( ! defined( 'IP_GEO_BLOCK_DEBUG' ) || ! IP_GEO_BLOCK_DEBUG ?
113
+ 'js/gmap.min.js' : 'js/gmap.js', __FILE__
114
+ ),
115
+ $dependency, IP_Geo_Block::VERSION, $footer
116
+ );
117
+ wp_enqueue_script( IP_Geo_Block::PLUGIN_NAME . '-google-map',
118
+ '//maps.googleapis.com/maps/api/js' . ( 'default' !== $key ? "?key=$key" : '' ),
119
+ $dependency, IP_Geo_Block::VERSION, $footer
120
+ );
121
+ }
122
+ wp_enqueue_script( IP_Geo_Block::PLUGIN_NAME . '-whois-js',
123
+ plugins_url( ! defined( 'IP_GEO_BLOCK_DEBUG' ) || ! IP_GEO_BLOCK_DEBUG ?
124
+ 'js/whois.min.js' : 'js/whois.js', __FILE__
125
+ ),
126
+ $dependency, IP_Geo_Block::VERSION, $footer
127
+ );
128
+ break;
129
+
130
+ case 4:
131
+ // footable https://github.com/bradvin/FooTable
132
+ wp_enqueue_style( IP_Geo_Block::PLUGIN_NAME . '-footable-css',
133
+ plugins_url( 'css/footable.core.min.css', __FILE__ ),
134
+ array(), IP_Geo_Block::VERSION
135
+ );
136
+ wp_enqueue_script( IP_Geo_Block::PLUGIN_NAME . '-footable-js',
137
+ plugins_url( 'js/footable.min.js', __FILE__ ),
138
+ $dependency, IP_Geo_Block::VERSION, $footer
139
+ );
140
+ }
141
+
142
+ // js for IP Geo Block admin page
143
+ wp_register_script(
144
+ $handle = IP_Geo_Block::PLUGIN_NAME . '-admin-script',
145
+ plugins_url( ! defined( 'IP_GEO_BLOCK_DEBUG' ) || ! IP_GEO_BLOCK_DEBUG ?
146
+ 'js/admin.min.js' : 'js/admin.js', __FILE__
147
+ ),
148
+ $dependency + ( isset( $addon ) ? array( $addon ) : array() ),
149
+ IP_Geo_Block::VERSION,
150
+ $footer
151
+ );
152
+ wp_localize_script( $handle,
153
+ 'IP_GEO_BLOCK',
154
+ array(
155
+ 'action' => 'ip_geo_block',
156
+ 'tab' => $this->admin_tab,
157
+ 'url' => admin_url( 'admin-ajax.php' ),
158
+ 'nonce' => IP_Geo_Block_Util::create_nonce( $this->get_ajax_action() ),
159
+ 'msg' => array(
160
+ __( 'Import settings ?', 'ip-geo-block' ),
161
+ __( 'Create table ?', 'ip-geo-block' ),
162
+ __( 'Delete table ?', 'ip-geo-block' ),
163
+ __( 'Clear statistics ?', 'ip-geo-block' ),
164
+ __( 'Clear cache ?', 'ip-geo-block' ),
165
+ __( 'Clear logs ?', 'ip-geo-block' ),
166
+ __( 'This feature is available with HTML5 compliant browsers.', 'ip-geo-block' ),
167
+ ),
168
+ )
169
+ );
170
+ wp_enqueue_script( $handle );
171
+ }
172
+
173
+ /**
174
+ * Add nonce to revision @since 4.4.0
175
+ *
176
+ */
177
+ public function add_revision_nonce( $revisions_data, $revision, $post ) {
178
+ $revisions_data['restoreUrl'] = add_query_arg(
179
+ $nonce = IP_Geo_Block::PLUGIN_NAME . '-auth-nonce',
180
+ IP_Geo_Block_Util::create_nonce( $nonce ),
181
+ $revisions_data['restoreUrl']
182
+ );
183
+
184
+ return $revisions_data;
185
+ }
186
+
187
+ /**
188
+ * Add plugin meta links
189
+ *
190
+ */
191
+ public function add_plugin_meta_links( $links, $file ) {
192
+ if ( $file === IP_GEO_BLOCK_BASE ) {
193
+ $title = __( 'Contribute at GitHub', 'ip-geo-block' );
194
+ array_push(
195
+ $links,
196
+ "<a href=\"http://www.ipgeoblock.com\" title=\"$title\" target=_blank>$title</a>"
197
+ );
198
+ }
199
+
200
+ return $links;
201
+ }
202
+
203
+ /**
204
+ * Add settings action link to the plugins page.
205
+ *
206
+ */
207
+ public function add_action_links( $links ) {
208
+ return array_merge(
209
+ array(
210
+ 'settings' => '<a href="' . esc_url( admin_url( 'options-general.php?page=' . IP_Geo_Block::PLUGIN_NAME ) ) . '">' . __( 'Settings' ) . '</a>'
211
+ ),
212
+ $links
213
+ );
214
+ }
215
+
216
+ /**
217
+ * Show global notice.
218
+ *
219
+ */
220
+ public function show_admin_notices() {
221
+ $key = IP_Geo_Block::PLUGIN_NAME . '-notice';
222
+
223
+ if ( FALSE !== ( $notices = get_transient( $key ) ) ) {
224
+ foreach ( $notices as $msg => $type ) {
225
+ echo "\n", '<div class="notice is-dismissible ', esc_attr( $type ), '"><p>';
226
+ if ( 'updated' === $type )
227
+ echo '<strong>', IP_Geo_Block_Util::kses( $msg ), '</strong>';
228
+ else
229
+ echo '<strong>IP Geo Block:</strong> ', IP_Geo_Block_Util::kses( $msg );
230
+ echo '</p></div>', "\n";
231
+ }
232
+ }
233
+
234
+ // delete all admin noties
235
+ delete_transient( $key );
236
+ }
237
+
238
+ /**
239
+ * Add global notice.
240
+ *
241
+ */
242
+ public static function add_admin_notice( $type, $msg ) {
243
+ $key = IP_Geo_Block::PLUGIN_NAME . '-notice';
244
+ if ( FALSE === ( $notices = get_transient( $key ) ) )
245
+ $notices = array();
246
+
247
+ // can't overwrite the existent notice
248
+ if ( ! isset( $notices[ $msg ] ) ) {
249
+ $notices[ $msg ] = $type;
250
+ set_transient( $key, $notices, MINUTE_IN_SECONDS );
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Register the administration menu into the WordPress Dashboard menu.
256
+ *
257
+ */
258
+ private function add_plugin_admin_menu() {
259
+ // Setup the tab number
260
+ $this->admin_tab = isset( $_GET['tab'] ) ? (int)$_GET['tab'] : 0;
261
+ $this->admin_tab = min( 4, max( 0, $this->admin_tab ) );
262
+
263
+ // Add a settings page for this plugin to the Settings menu.
264
+ $hook = add_options_page(
265
+ __( 'IP Geo Block', 'ip-geo-block' ),
266
+ __( 'IP Geo Block', 'ip-geo-block' ),
267
+ 'manage_options',
268
+ IP_Geo_Block::PLUGIN_NAME,
269
+ array( $this, 'display_plugin_admin_page' )
270
+ );
271
+
272
+ // If successful, load admin assets only on this page.
273
+ if ( $hook )
274
+ add_action( "load-$hook", array( $this, 'enqueue_admin_assets' ) );
275
+ }
276
+
277
+ /**
278
+ * Diagnosis of admin settings.
279
+ *
280
+ */
281
+ private function diagnose_admin_screen() {
282
+ // Check version and compatibility
283
+ if ( version_compare( get_bloginfo( 'version' ), '3.7.0' ) < 0 )
284
+ self::add_admin_notice( 'error', __( 'You need WordPress 3.7+.', 'ip-geo-block' ) );
285
+
286
+ $settings = IP_Geo_Block::get_option();
287
+ $adminurl = 'options-general.php';
288
+
289
+ // Check consistency of matching rule
290
+ if ( -1 === (int)$settings['matching_rule'] ) {
291
+ if ( FALSE !== get_transient( IP_Geo_Block::CRON_NAME ) ) {
292
+ self::add_admin_notice( 'notice-warning', sprintf(
293
+ __( 'Now downloading geolocation databases in background. After a little while, please check your country code and &#8220;<strong>Matching rule</strong>&#8221; at <a href="%s">Validation rule settings</a>.', 'ip-geo-block' ),
294
+ esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME ), $adminurl ) )
295
+ ) );
296
+ }
297
+ else {
298
+ self::add_admin_notice( 'error', sprintf(
299
+ __( 'The &#8220;<strong>Matching rule</strong>&#8221; is not set properly. Please confirm it at <a href="%s">Validation rule settings</a>.', 'ip-geo-block' ),
300
+ esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME ), $adminurl ) )
301
+ ) );
302
+ }
303
+ }
304
+
305
+ // Check to finish updating matching rule
306
+ elseif ( 'done' === get_transient( IP_Geo_Block::CRON_NAME ) ) {
307
+ delete_transient( IP_Geo_Block::CRON_NAME );
308
+ self::add_admin_notice( 'updated ', __( 'Local database and matching rule have been updated.', 'ip-geo-block' ) );
309
+ }
310
+
311
+ // Check self blocking
312
+ if ( 1 === (int)$settings['validation']['login'] ) {
313
+ $instance = IP_Geo_Block::get_instance();
314
+ $validate = $instance->validate_ip( 'login', $settings, TRUE, FALSE, FALSE ); // skip authentication check
315
+
316
+ switch( $validate['result'] ) {
317
+ case 'limited':
318
+ self::add_admin_notice( 'error',
319
+ __( 'Once you logout, you will be unable to login again because the number of login attempts reaches the limit.', 'ip-geo-block' ) . ' ' .
320
+ sprintf(
321
+ __( 'Please execute "<strong>Clear cache</strong>" on <a href="%s">Statistics tab</a> to prevent locking yourself out.', 'ip-geo-block' ),
322
+ esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME, 'tab' => 1 ), $adminurl ) )
323
+ )
324
+ );
325
+ break;
326
+
327
+ case 'blocked':
328
+ case 'extra':
329
+ self::add_admin_notice( 'error',
330
+ ( $settings['matching_rule'] ?
331
+ __( 'Once you logout, you will be unable to login again because your country code or IP address is in the blacklist.', 'ip-geo-block' ) :
332
+ __( 'Once you logout, you will be unable to login again because your country code or IP address is not in the whitelist.', 'ip-geo-block' )
333
+ ) .
334
+ sprintf(
335
+ __( 'Please check your <a href="%s">Validation rule settings</a>.', 'ip-geo-block' ),
336
+ esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME ), $adminurl ) ) . '#' . IP_Geo_Block::PLUGIN_NAME . '-settings-0'
337
+ )
338
+ );
339
+ }
340
+ }
341
+
342
+ if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ) {
343
+ // Check creation of database table
344
+ if ( $settings['validation']['reclogs'] ) {
345
+ if ( ( $warn = IP_Geo_Block_Logs::diag_tables() ) &&
346
+ FALSE === IP_Geo_Block_Logs::create_tables() ) {
347
+ self::add_admin_notice( 'notice-warning', $warn );
348
+ }
349
+ }
350
+ }
351
+ }
352
+
353
+ /**
354
+ * Setup menu and option page for this plugin
355
+ *
356
+ */
357
+ public function setup_admin_page() {
358
+ // Avoid multiple validation.
359
+ if ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
360
+ $this->diagnose_admin_screen();
361
+ $this->add_plugin_admin_menu();
362
+ }
363
+
364
+ // Register settings page only if it is needed.
365
+ if ( ( isset( $_GET ['page' ] ) && IP_Geo_Block::PLUGIN_NAME === $_GET ['page' ] ) ||
366
+ ( isset( $_POST['option_page'] ) && IP_Geo_Block::PLUGIN_NAME === $_POST['option_page'] ) ) {
367
+ $this->register_settings_tab();
368
+ }
369
+
370
+ // Add an action link pointing to the options page. @since 2.7
371
+ else {
372
+ add_filter( 'plugin_row_meta', array( $this, 'add_plugin_meta_links' ), 10, 2 );
373
+ add_filter( 'plugin_action_links_' . IP_GEO_BLOCK_BASE, array( $this, 'add_action_links' ), 10, 1 );
374
+ }
375
+
376
+ // Register scripts for admin.
377
+ add_action( 'admin_enqueue_scripts', array( 'IP_Geo_Block', 'enqueue_nonce' ) );
378
+
379
+ // Show admin notices at the place where it should be.
380
+ add_action( 'admin_notices', array( $this, 'show_admin_notices' ) );
381
+ }
382
+
383
+ /**
384
+ * Render the settings page for this plugin.
385
+ *
386
+ */
387
+ public function display_plugin_admin_page() {
388
+ $tab = $this->admin_tab;
389
+ $tabs = array(
390
+ 0 => __( 'Settings', 'ip-geo-block' ),
391
+ 1 => __( 'Statistics', 'ip-geo-block' ),
392
+ 4 => __( 'Logs', 'ip-geo-block' ),
393
+ 2 => __( 'Search', 'ip-geo-block' ),
394
+ 3 => __( 'Attribution', 'ip-geo-block' ),
395
+ );
396
+ ?>
397
+ <div class="wrap">
398
+ <h2><?php echo esc_html( get_admin_page_title() ); ?></h2>
399
+ <h2 class="nav-tab-wrapper">
400
+ <?php foreach ( $tabs as $key => $val ) {
401
+ echo '<a href="?page=', IP_Geo_Block::PLUGIN_NAME, '&amp;tab=', $key, '" class="nav-tab', ($tab === $key ? ' nav-tab-active' : ''), '">', $val, '</a>';
402
+ } ?>
403
+ </h2>
404
+ <?php if ( 0 <= $tab && $tab <= 1 ) { ?>
405
+ <p style="text-align:left">[ <a id="ip-geo-block-toggle-sections" href="javascript:void(0)"><?php _e( 'Toggle all', 'ip-geo-block' ); ?></a> ]</p>
406
+ <?php } ?>
407
+ <form method="post" action="options.php"<?php if ( 0 !== $tab ) echo " id=\"", IP_Geo_Block::PLUGIN_NAME, "-inhibit\""; ?>>
408
+ <?php
409
+ settings_fields( IP_Geo_Block::PLUGIN_NAME );
410
+ do_settings_sections( IP_Geo_Block::PLUGIN_NAME );
411
+ if ( 0 === $tab )
412
+ submit_button(); // @since 3.1
413
+ ?>
414
+ </form>
415
+ <?php if ( 2 === $tab ) { ?>
416
+ <div id="ip-geo-block-whois"></div>
417
+ <div id="ip-geo-block-map"></div>
418
+ <?php } elseif ( 3 === $tab ) {
419
+ // show attribution (higher priority order)
420
+ $providers = IP_Geo_Block_Provider::get_addons();
421
+ $tab = array();
422
+ foreach ( $providers as $provider ) {
423
+ if ( $geo = IP_Geo_Block_API::get_instance( $provider, NULL ) ) {
424
+ $tab[] = $geo->get_attribution();
425
+ }
426
+ }
427
+ echo '<p>', implode( '<br />', $tab ), "</p>\n";
428
+
429
+ echo "<p>", __( 'Thanks for providing these great services for free.', 'ip-geo-block' ), "<br />\n";
430
+ echo __( '(Most browsers will redirect you to each site <a href="http://www.ipgeoblock.com/etc/referer.html" title="Referer Checker">without referrer when you click the link</a>.)', 'ip-geo-block' ), "</p>\n";
431
+ } ?>
432
+ <?php if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ) {
433
+ echo '<p>', get_num_queries(), ' queries. ', timer_stop(0), ' seconds. ', memory_get_usage(), " bytes.</p>\n";
434
+ } ?>
435
+ <p style="margin:0; text-align:right">[ <a id="ip-geo-block-back-to-top" href="#"><?php _e( 'Back to top', 'ip-geo-block' ); ?></a> ]</p>
436
+ </div>
437
+ <?php
438
+ }
439
+
440
+ /**
441
+ * Initializes the options page by registering the Sections, Fields, and Settings
442
+ *
443
+ */
444
+ private function register_settings_tab() {
445
+ $files = array(
446
+ 0 => 'admin/includes/tab-settings.php',
447
+ 1 => 'admin/includes/tab-statistics.php',
448
+ 4 => 'admin/includes/tab-accesslog.php',
449
+ 2 => 'admin/includes/tab-geolocation.php',
450
+ 3 => 'admin/includes/tab-attribution.php',
451
+ );
452
+
453
+ require_once IP_GEO_BLOCK_PATH . $files[ $this->admin_tab ];
454
+ IP_Geo_Block_Admin_Tab::tab_setup( $this );
455
+ }
456
+
457
+ /**
458
+ * Function that fills the field with the desired inputs as part of the larger form.
459
+ * The 'id' and 'name' should match the $id given in the add_settings_field().
460
+ * @param array $args['value'] must be sanitized because it comes from external.
461
+ */
462
+ public function callback_field( $args ) {
463
+ if ( ! empty( $args['before'] ) )
464
+ echo $args['before'], "\n"; // must be sanitized at caller
465
+
466
+ // field
467
+ $id = $name = '';
468
+ if ( ! empty( $args['field'] ) ) {
469
+ $id = "${args['option']}_${args['field']}";
470
+ $name = "${args['option']}[${args['field']}]";
471
+ }
472
+
473
+ // sub field
474
+ $sub_id = $sub_name = '';
475
+ if ( ! empty( $args['sub-field'] ) ) {
476
+ $sub_id = "_${args['sub-field']}";
477
+ $sub_name = "[${args['sub-field']}]";
478
+ }
479
+
480
+ switch ( $args['type'] ) {
481
+
482
+ case 'check-provider':
483
+ echo "\n<ul class=\"ip-geo-block-list\">\n";
484
+ foreach ( $args['providers'] as $key => $val ) {
485
+ $id = "${args['option']}_providers_{$key}";
486
+ $name = "${args['option']}[providers][$key]"; ?>
487
+ <li>
488
+ <input type="checkbox" id="<?php echo $id; ?>" name="<?php echo $name; ?>" value="<?php echo $val; ?>"<?php
489
+ checked(
490
+ ( NULL === $val && ! isset( $args['value'][ $key ] ) ) ||
491
+ ( FALSE === $val && ! empty( $args['value'][ $key ] ) ) ||
492
+ ( is_string( $val ) && ! empty( $args['value'][ $key ] ) )
493
+ ); ?> />
494
+ <label for="<?php echo $id; ?>"><?php echo '<dfn title="', esc_attr( $args['titles'][ $key ] ), '">', $key, '</dfn>'; ?></label>
495
+ <?php
496
+ if ( is_string( $val ) ) { ?>
497
+ <input type="text" class="regular-text code" name="<?php echo $name; ?>" value="<?php echo esc_attr( isset( $args['value'][ $key ] ) ? $args['value'][ $key ] : '' ); ?>"<?php if ( ! isset( $val ) ) disabled( TRUE, TRUE ); ?> />
498
+ </li>
499
+ <?php
500
+ }
501
+ }
502
+ echo "</ul>\n";
503
+ break;
504
+
505
+ case 'checkboxes':
506
+ echo "\n<ul class=\"ip-geo-block-list\">\n";
507
+ foreach ( $args['list'] as $key => $val ) { ?>
508
+ <li>
509
+ <input type="checkbox" id="<?php echo $id, $sub_id, '_', $key; ?>" name="<?php echo $name, $sub_name, '[', $key, ']'; ?>" value="<?php echo $key; ?>"<?php
510
+ checked( $key & $args['value'] ? TRUE : FALSE ); ?> />
511
+ <label for="<?php echo $id, $sub_id, '_', $key; ?>"><?php
512
+ if ( isset( $args['desc'][ $key ] ) )
513
+ echo '<dfn title="', $args['desc'][ $key ], '">', $val, '</dfn>';
514
+ else
515
+ echo $val;
516
+ ?></label>
517
+ </li>
518
+ <?php
519
+ }
520
+ echo "</ul>\n";
521
+ break;
522
+
523
+ case 'checkbox': ?>
524
+ <input type="checkbox" id="<?php echo $id, $sub_id; ?>" name="<?php echo $name, $sub_name; ?>" value="1"<?php
525
+ checked( esc_attr( $args['value'] ) );
526
+ disabled( ! empty( $args['disabled'] ), TRUE ); ?> />
527
+ <label for="<?php echo $id, $sub_id; ?>"><?php echo esc_attr( isset( $args['text'] ) ? $args['text'] : __( 'Enable', 'ip-geo-block' ) ); ?></label>
528
+ <?php
529
+ break;
530
+
531
+ case 'select':
532
+ case 'select-text':
533
+ echo "\n<select id=\"${id}${sub_id}\" name=\"${name}${sub_name}\">\n";
534
+ foreach ( $args['list'] as $key => $val ) {
535
+ echo "\t<option value=\"$key\"", ( NULL === $val ? ' selected disabled' : selected( $args['value'], $key, FALSE ) );
536
+ if ( isset( $args['desc'][ $key ] ) )
537
+ echo " data-desc=\"", $args['desc'][ $key ], "\"";
538
+ echo ">$val</option>\n";
539
+ }
540
+ echo "</select>\n";
541
+ if ( 'select' === $args['type'] )
542
+ break;
543
+ echo "<br />\n";
544
+ $sub_id = '_' . $args['txt-field']; // possible value of 'txt-field' is 'msg'
545
+ $sub_name = '[' . $args['txt-field'] . ']';
546
+ $args['value'] = $args['text']; // should be escaped because it can contain allowed tags
547
+
548
+ case 'text': ?>
549
+ <input type="text" class="regular-text code" id="<?php echo $id, $sub_id; ?>" name="<?php echo $name, $sub_name; ?>" value="<?php echo esc_attr( $args['value'] ); ?>"
550
+ <?php disabled( ! empty( $args['disabled'] ), TRUE ); ?> />
551
+ <?php
552
+ break; // disabled @since 3.0
553
+
554
+ case 'textarea': ?>
555
+ <textarea class="regular-text code" id="<?php echo $id, $sub_id; ?>" name="<?php echo $name, $sub_name; ?>"
556
+ <?php disabled( ! empty( $args['disabled'] ), TRUE ); ?>><?php echo esc_html( $args['value'] ); ?></textarea>
557
+ <?php
558
+ break;
559
+
560
+ case 'button': ?>
561
+ <input type="button" class="button-secondary" id="<?php echo $id; ?>" value="<?php echo esc_attr( $args['value'] ); ?>"
562
+ <?php disabled( ! empty( $args['disabled'] ), TRUE ); ?>/>
563
+ <?php
564
+ break;
565
+
566
+ case 'html':
567
+ echo "\n", $args['value'], "\n"; // must be sanitized at caller
568
+ break;
569
+ }
570
+
571
+ if ( ! empty( $args['after'] ) )
572
+ echo $args['after'], "\n"; // must be sanitized at caller
573
+ }
574
+
575
+ /**
576
+ * Sanitize options before saving them into DB.
577
+ *
578
+ * @param array $input The values to be validated.
579
+ *
580
+ * @link http://codex.wordpress.org/Validating_Sanitizing_and_Escaping_User_Data
581
+ * @link http://codex.wordpress.org/Function_Reference/sanitize_option
582
+ * @link http://codex.wordpress.org/Function_Reference/sanitize_text_field
583
+ * @link http://codex.wordpress.org/Plugin_API/Filter_Reference/sanitize_option_$option
584
+ * @link https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php
585
+ */
586
+ public function validate_options( $input ) {
587
+ // setup base options
588
+ $output = IP_Geo_Block::get_option();
589
+ $default = IP_Geo_Block::get_default();
590
+
591
+ // checkboxes not on the form (added after 2.0.0, just in case)
592
+ foreach ( array( 'anonymize', 'network_wide' ) as $key ) {
593
+ $output[ $key ] = 0;
594
+ }
595
+
596
+ // checkboxes not on the form
597
+ foreach ( array( 'login', 'admin', 'ajax', 'plugins', 'themes', 'public' ) as $key ) {
598
+ $output['validation'][ $key ] = 0;
599
+ }
600
+
601
+ // restore the 'signature' that might be transformed to avoid self blocking
602
+ if ( isset( $input['signature'] ) && FALSE === strpos( $input['signature'], ',' ) )
603
+ $input['signature'] = str_rot13( base64_decode( $input['signature'] ) );
604
+
605
+ /**
606
+ * Sanitize a string from user input
607
+ */
608
+ foreach ( $output as $key => $val ) {
609
+ $key = sanitize_text_field( $key );
610
+
611
+ // delete old key
612
+ if ( ! array_key_exists( $key, $default ) ) {
613
+ unset( $output[ $key ] );
614
+ continue;
615
+ }
616
+
617
+ switch( $key ) {
618
+ case 'providers':
619
+ foreach ( IP_Geo_Block_Provider::get_providers() as $provider => $api ) {
620
+ // need no key
621
+ if ( NULL === $api ) {
622
+ if ( isset( $input[ $key ][ $provider ] ) )
623
+ unset( $output[ $key ][ $provider ] );
624
+ else
625
+ $output['providers'][ $provider ] = '';
626
+ }
627
+
628
+ // non-commercial
629
+ elseif ( FALSE === $api ) {
630
+ if ( isset( $input[ $key ][ $provider ] ) )
631
+ $output['providers'][ $provider ] = '@';
632
+ else
633
+ unset( $output[ $key ][ $provider ] );
634
+ }
635
+
636
+ // need key
637
+ else {
638
+ $output[ $key ][ $provider ] =
639
+ isset( $input[ $key ][ $provider ] ) ?
640
+ sanitize_text_field( $input[ $key ][ $provider ] ) : '';
641
+ }
642
+ }
643
+
644
+ // Check providers setting
645
+ if ( $error = IP_Geo_Block_Provider::diag_providers( $output[ $key ] ) )
646
+ self::add_admin_notice( 'error', $error );
647
+ break;
648
+
649
+ case 'comment':
650
+ if ( isset( $input[ $key ]['pos'] ) )
651
+ $output[ $key ]['pos'] = (int)$input[ $key ]['pos'];
652
+
653
+ if ( isset( $input[ $key ]['msg'] ) )
654
+ $output[ $key ]['msg'] = IP_Geo_Block_Util::kses( $input[ $key ]['msg'] );
655
+ break;
656
+
657
+ case 'white_list':
658
+ case 'black_list':
659
+ $output[ $key ] = isset( $input[ $key ] ) ?
660
+ sanitize_text_field(
661
+ preg_replace( '/[^A-Z,]/', '', strtoupper( $input[ $key ] ) )
662
+ ) : '';
663
+ break;
664
+
665
+ default: // checkbox, select, text
666
+ // single field
667
+ if ( ! is_array( $default[ $key ] ) ) {
668
+ // for checkbox
669
+ if ( is_bool( $default[ $key ] ) ) {
670
+ $output[ $key ] = ! empty( $input[ $key ] );
671
+ }
672
+
673
+ // otherwise if implicit
674
+ elseif ( isset( $input[ $key ] ) ) {
675
+ $output[ $key ] = is_int( $default[ $key ] ) ?
676
+ (int)$input[ $key ] :
677
+ IP_Geo_Block_Util::kses( trim( $input[ $key ] ), FALSE );
678
+ }
679
+ }
680
+
681
+ // sub field
682
+ else foreach ( array_keys( (array)$val ) as $sub ) {
683
+ // delete old key
684
+ if ( ! array_key_exists( $sub, $default[ $key ] ) ) {
685
+ unset( $output[ $key ][ $sub ] );
686
+ }
687
+
688
+ // for checkbox
689
+ elseif ( is_bool( $default[ $key ][ $sub ] ) ) {
690
+ $output[ $key ][ $sub ] = ! empty( $input[ $key ][ $sub ] );
691
+ }
692
+
693
+ // for array
694
+ elseif ( is_array( $default[ $key ][ $sub ] ) ) {
695
+ $output[ $key ][ $sub ] = empty( $input[ $key ][ $sub ] ) ?
696
+ array() : $input[ $key ][ $sub ];
697
+ }
698
+
699
+ // otherwise if implicit
700
+ elseif ( isset( $input[ $key ][ $sub ] ) ) {
701
+ // for checkboxes
702
+ if ( is_array( $input[ $key ][ $sub ] ) ) {
703
+ foreach ( $input[ $key ][ $sub ] as $k => $v ) {
704
+ $output[ $key ][ $sub ] |= $v;
705
+ }
706
+ }
707
+
708
+ else {
709
+ $output[ $key ][ $sub ] = ( is_int( $default[ $key ][ $sub ] ) ?
710
+ (int)$input[ $key ][ $sub ] :
711
+ IP_Geo_Block_Util::kses( trim( $input[ $key ][ $sub ] ), FALSE )
712
+ );
713
+ }
714
+ }
715
+ }
716
+ }
717
+ }
718
+
719
+ //----------------------------------------
720
+ // Check and format each setting data
721
+ //----------------------------------------
722
+
723
+ // sanitize proxy
724
+ $output['validation']['proxy'] = implode( ',', $this->trim(
725
+ preg_replace( '/[^\w,]/', '', strtoupper( $output['validation']['proxy'] ) )
726
+ ) );
727
+
728
+ // sanitize and format ip address
729
+ $key = array( '/[^\d\n\.\/,:]/', '/([\s,])+/', '/(?:^,|,$)/' );
730
+ $val = array( '', '$1', '' );
731
+ $output['extra_ips']['white_list'] = preg_replace( $key, $val, trim( $output['extra_ips']['white_list'] ) );
732
+ $output['extra_ips']['black_list'] = preg_replace( $key, $val, trim( $output['extra_ips']['black_list'] ) );
733
+
734
+ // format signature, ua_list (text area)
735
+ array_shift( $key );
736
+ array_shift( $val );
737
+ $output['signature'] = preg_replace( $key, $val, trim( $output['signature'] ) );
738
+
739
+ // 3.0.0 convert country code to upper case, remove redundant spaces
740
+ $output['public']['ua_list'] = preg_replace( $key, $val, trim( $output['public']['ua_list'] ) );
741
+ $output['public']['ua_list'] = preg_replace( '/([:#]) *([!]+) *([^ ]+) *([,\n]+)/', '$1$2$3$4', $output['public']['ua_list'] );
742
+ $output['public']['ua_list'] = preg_replace_callback( '/[:#]\w+/', array( $this, 'strtoupper' ), $output['public']['ua_list'] );
743
+
744
+ // reject invalid signature which potentially blocks itself
745
+ $output['signature'] = implode( ',', $this->trim( $output['signature'] ) );
746
+
747
+ // 2.2.5 exception : convert associative array to simple array
748
+ foreach ( array( 'plugins', 'themes' ) as $key ) {
749
+ $output['exception'][ $key ] = array_keys( $output['exception'][ $key ] );
750
+ }
751
+
752
+ // 3.0.0 public : convert country code to upper case
753
+ foreach ( array( 'white_list', 'black_list' ) as $key ) {
754
+ $output['public'][ $key ] = strtoupper( preg_replace( '/\s/', '', $output['public'][ $key ] ) );
755
+ }
756
+
757
+ // 3.0.0 exception : trim extra space and comma
758
+ foreach ( array( 'admin', 'public', 'includes', 'uploads', 'languages' ) as $key ) {
759
+ if ( empty( $output['exception'][ $key ] ) ) {
760
+ $output['exception'][ $key ] = $default['exception'][ $key ];
761
+ } else {
762
+ $output['exception'][ $key ] = ( is_array( $output['exception'][ $key ] ) ?
763
+ $output['exception'][ $key ] : $this->trim( $output['exception'][ $key ] ) );
764
+ }
765
+ }
766
+
767
+ return $output;
768
+ }
769
+
770
+ // Callback for preg_replace_callback()
771
+ public function strtoupper( $matches ) {
772
+ return strtoupper( $matches[0] );
773
+ }
774
+
775
+ // Trim extra space and comma avoiding invalid signature which potentially blocks itself
776
+ private function trim( $text ) {
777
+ $ret = array();
778
+ foreach ( explode( ',', $text ) as $val ) {
779
+ $val = trim( $val );
780
+ if ( $val && FALSE === stripos( IP_Geo_Block::$wp_path['admin'], $val ) ) {
781
+ $ret[] = $val;
782
+ }
783
+ }
784
+ return $ret;
785
+ }
786
+
787
+ /**
788
+ * Check admin post
789
+ *
790
+ */
791
+ private function check_admin_post( $ajax = FALSE ) {
792
+ if ( FALSE === $ajax ) {
793
+ // a postfix '-options' is added at settings_fields().
794
+ $nonce = check_admin_referer( IP_Geo_Block::PLUGIN_NAME . '-options' );
795
+ } else {
796
+ $nonce = IP_Geo_Block_Util::verify_nonce( IP_Geo_Block_Util::retrieve_nonce( 'nonce' ), $this->get_ajax_action() );
797
+ }
798
+
799
+ $action = IP_Geo_Block::PLUGIN_NAME . '-auth-nonce';
800
+ $nonce &= IP_Geo_Block_Util::verify_nonce( IP_Geo_Block_Util::retrieve_nonce( $action ), $action );
801
+
802
+ if ( ! $nonce || ( ! current_user_can( 'manage_options' ) ) ) {
803
+ status_header( 403 );
804
+ wp_die(
805
+ __( 'You do not have sufficient permissions to access this page.' ), '',
806
+ array( 'response' => 403, 'back_link' => TRUE )
807
+ );
808
+ }
809
+ }
810
+
811
+ /**
812
+ * Validate settings and configure some features.
813
+ *
814
+ */
815
+ public function validate_settings( $input = array() ) {
816
+ // must check that the user has the required capability
817
+ $this->check_admin_post( FALSE );
818
+
819
+ // validate setting options
820
+ $options = $this->validate_options( $input );
821
+
822
+ // activate rewrite rules
823
+ require_once IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-rewrite.php';
824
+ $stat = IP_Geo_Block_Admin_Rewrite::activate_rewrite_all( $options['rewrite'] );
825
+
826
+ // check the status of rewrite rules
827
+ $diff = array_diff_assoc( $options['rewrite'], $stat );
828
+ if ( ! empty( $diff ) ) {
829
+ $options['rewrite'] = $stat;
830
+
831
+ $file = array();
832
+ $dirs = IP_Geo_Block_Admin_Rewrite::get_dirs();
833
+
834
+ // show which file would be the issue
835
+ foreach ( $diff as $key => $stat ) {
836
+ $file[] = '<code>' . $dirs[ $key ] . '.htaccess</code>';
837
+ }
838
+
839
+ self::add_admin_notice( 'error',
840
+ sprintf( __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ), implode( ', ', $file ) ) . '&nbsp;' .
841
+ sprintf( _n( 'Or please refer to %s to set it manually.', 'Or please refer to %s to set them manually.', count( $file ), 'ip-geo-block' ), '<a href="http://ipgeoblock.com/codex/how-to-fix-permission-troubles.html" title="How to fix permission troubles? | IP Geo Block">How to fix permission troubles?</a>' )
842
+ );
843
+ }
844
+
845
+ // additional configuration
846
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php';
847
+ $file = IP_Geo_Block_Opts::setup_validation_timing( $options );
848
+ if ( TRUE !== $file ) {
849
+ $options['validation']['timing'] = 0;
850
+ self::add_admin_notice( 'error', sprintf(
851
+ __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ), $file
852
+ ) );
853
+ }
854
+
855
+ // Force to finish update matching rule
856
+ delete_transient( IP_Geo_Block::CRON_NAME );
857
+
858
+ return $options;
859
+ }
860
+
861
+ /**
862
+ * Ajax callback function
863
+ *
864
+ * @link http://codex.wordpress.org/AJAX_in_Plugins
865
+ * @link http://codex.wordpress.org/Function_Reference/check_ajax_referer
866
+ * @link http://core.trac.wordpress.org/browser/trunk/wp-admin/admin-ajax.php
867
+ */
868
+ public function admin_ajax_callback() {
869
+ // Check request origin, nonce, capability.
870
+ $this->check_admin_post( TRUE );
871
+
872
+ require_once IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-ajax.php';
873
+
874
+ $which = isset( $_POST['which'] ) ? $_POST['which'] : NULL;
875
+ switch ( isset( $_POST['cmd' ] ) ? $_POST['cmd' ] : NULL ) {
876
+ case 'download':
877
+ $res = IP_Geo_Block::get_instance();
878
+ $res = $res->update_database();
879
+ break;
880
+
881
+ case 'search':
882
+ // Get geolocation by IP
883
+ $res = IP_Geo_Block_Admin_Ajax::search_ip( $which );
884
+ break;
885
+
886
+ case 'scan-code':
887
+ // Fetch providers to get country code
888
+ $res = IP_Geo_Block_Admin_Ajax::scan_country();
889
+ break;
890
+
891
+ case 'clear-statistics':
892
+ // Set default values
893
+ IP_Geo_Block_Logs::clear_stat();
894
+ $res = array(
895
+ 'page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_NAME,
896
+ 'tab' => 'tab=1'
897
+ );
898
+ break;
899
+
900
+ case 'clear-cache':
901
+ // Delete cache of IP address
902
+ IP_Geo_Block_API_Cache::clear_cache();
903
+ $res = array(
904
+ 'page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_NAME,
905
+ 'tab' => 'tab=1'
906
+ );
907
+ break;
908
+
909
+ case 'clear-logs':
910
+ // Delete logs in MySQL DB
911
+ $hook = array( 'comment', 'login', 'admin', 'xmlrpc', 'public' );
912
+ $which = in_array( $which, $hook ) ? $which : NULL;
913
+ IP_Geo_Block_Logs::clear_logs( $which );
914
+ $res = array(
915
+ 'page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_NAME,
916
+ 'tab' => 'tab=4'
917
+ );
918
+ break;
919
+
920
+ case 'export-logs':
921
+ // Export logs from MySQL DB
922
+ IP_Geo_Block_Admin_Ajax::export_logs( $which );
923
+ break;
924
+
925
+ case 'restore':
926
+ // Get logs from MySQL DB
927
+ $res = IP_Geo_Block_Admin_Ajax::restore_logs( $which );
928
+ break;
929
+
930
+ case 'validate':
931
+ // Validate settings
932
+ IP_Geo_Block_Admin_Ajax::validate_settings( $this );
933
+ break;
934
+
935
+ case 'import-default':
936
+ // Import initial settings
937
+ $res = IP_Geo_Block_Admin_Ajax::settings_to_json( IP_Geo_Block::get_default() );
938
+ break;
939
+
940
+ case 'import-preferred':
941
+ // Import preference
942
+ $res = IP_Geo_Block_Admin_Ajax::preferred_to_json();
943
+ break;
944
+
945
+ case 'gmap-error':
946
+ // Reset Google Maps API key
947
+ $which = IP_Geo_Block::get_option();
948
+ if ( $which['api_key']['GoogleMap'] === 'default' ) {
949
+ $which['api_key']['GoogleMap'] = NULL;
950
+ update_option( IP_Geo_Block::OPTION_NAME, $which );
951
+ $res = array(
952
+ 'page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_SLUG,
953
+ 'tab' => 'tab=2'
954
+ );
955
+ }
956
+ break;
957
+
958
+ case 'show-info':
959
+ $res = IP_Geo_Block_Admin_Ajax::get_wp_info();
960
+ break;
961
+
962
+ case 'create-table':
963
+ case 'delete-table':
964
+ // Need to define `IP_GEO_BLOCK_DEBUG` to true
965
+ if ( 'create-table' === $_POST['cmd'] )
966
+ IP_Geo_Block_Logs::create_tables();
967
+ else
968
+ IP_Geo_Block_Logs::delete_tables();
969
+
970
+ $res = array(
971
+ 'page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_NAME,
972
+ );
973
+ break;
974
+ }
975
+
976
+ if ( isset( $res ) ) // wp_send_json_{success,error}() @since 3.5.0
977
+ wp_send_json( $res ); // @since 3.5.0
978
+
979
+ die(); // End of ajax
980
+ }
981
+
982
+ }
admin/css/admin.css ADDED
@@ -0,0 +1,379 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This stylesheet is used to style the admin option form of the plugin. */
2
+ dfn {
3
+ cursor: help;
4
+ border-bottom: 1px dotted #888;
5
+ }
6
+
7
+ /* legend and fieldset in the form */
8
+ .form-table {
9
+ margin: 0 1em;
10
+ }
11
+ fieldset.ip-geo-block-field {
12
+ border: 1px solid #ccc;
13
+ padding: 0.35em 0.625em 0.75em 1em;
14
+ margin: 1.35em 0 1.5em;
15
+ }
16
+ fieldset.ip-geo-block-field h2,
17
+ fieldset.ip-geo-block-field h3 {
18
+ padding: 0;
19
+ margin: 0;
20
+ }
21
+ fieldset.ip-geo-block-field .ip-geo-block-dropup,
22
+ fieldset.ip-geo-block-field .ip-geo-block-dropdown {
23
+ cursor: pointer;
24
+ position: relative;
25
+ padding-left: 1em;
26
+ }
27
+ fieldset.ip-geo-block-field .ip-geo-block-dropup:before,
28
+ fieldset.ip-geo-block-field .ip-geo-block-dropdown:before {
29
+ content: '';
30
+ height: 0;
31
+ width: 0;
32
+ border: 0.4em solid transparent;
33
+ position: absolute;
34
+ }
35
+ fieldset.ip-geo-block-field .ip-geo-block-dropup:before {
36
+ border-left: 0.4em solid #555;
37
+ left: 3px;
38
+ top: 15%;
39
+ }
40
+ fieldset.ip-geo-block-field .ip-geo-block-dropdown:before {
41
+ border-top: 0.4em solid #555;
42
+ left: 0;
43
+ top: 35%;
44
+ }
45
+ fieldset.ip-geo-block-field ul.ip-geo-block-dropup:before {
46
+ top: 0.25em;
47
+ }
48
+ fieldset.ip-geo-block-field ul.ip-geo-block-dropdown:before {
49
+ top: 0.45em;
50
+ }
51
+ fieldset.ip-geo-block-field .form-table {
52
+ margin: 0.5em 0 0;
53
+ }
54
+
55
+ textarea.regular-text {
56
+ width: 25em;
57
+ }
58
+
59
+ ul.ip_geo_block_settings_folding {
60
+ margin: 0.5em 0;
61
+ }
62
+ ul.ip_geo_block_settings_folding ul {
63
+ margin-bottom: 0;
64
+ }
65
+ ul.ip_geo_block_settings_folding li:first-child {
66
+ margin-top: 0.5em;
67
+ }
68
+ .folding-disable {
69
+ pointer-events: none;
70
+ opacity: 0.5;
71
+ }
72
+ .folding-inactive {
73
+ opacity: 0.5;
74
+ font-style:oblique !important;
75
+ }
76
+
77
+ .ip-geo-block-hide {
78
+ display: none;
79
+ }
80
+
81
+ .ip-geo-block-sup {
82
+ margin-left: 0.2em;
83
+ display: inline-block;
84
+ }
85
+
86
+ ul.ip-geo-block-note {
87
+ list-style: disc outside;
88
+ margin-left: 1em;
89
+ }
90
+ ul.ip-geo-block-list {
91
+ margin-top: 0.25em;
92
+ margin-bottom: 0.25em;
93
+ }
94
+ ul.ip-geo-block-list label {
95
+ display: inline-block;
96
+ }
97
+ .ip-geo-block-desc {
98
+ display: inline-block;
99
+ margin-top: 0.25em;
100
+ margin-bottom: 0.25em;
101
+ }
102
+ @media screen and (min-width:782px) {
103
+ ul.ip-geo-block-list .code {
104
+ width: 15em;
105
+ }
106
+ }
107
+
108
+ .ip-geo-block-loading {
109
+ background-size: 16px 16px;
110
+ background-position: center center;
111
+ background-repeat: no-repeat;
112
+ background-image: url(data:image/gif;base64,R0lGODlhEAAQAPIGAAAAAMLCwkJCQpKSkmJiYoKCgv///wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAGACwAAAAAEAAQAAADM2i63P4wyklrC0IEKgAQnAdOmGYFBLExwboQWcG2rlHEwTDQLUsUOd2mBxkUCgNKa+dIAAAh+QQJCgAGACwAAAIACgAOAAADLWgWIqHQCABEVLPe1R4MBOFFRFNsRUNsYDFewTC8iixvQ1EMyxjEvyBLODQkAAAh+QQJCgAGACwAAAAACgAOAAADLWi6IRJrCQCECoU0ag1xxeBARuEQ0UUU5DUM7fK+qTEUYR0EcM3Ev51uB7wAEwAh+QQJCgAGACwAAAAADgAKAAADLWi6URQrLiJEkSaM0eqrkLFtAVEEAgAIylAUQ5SuSqCFNZjhWG3zmB8wOJQkAAAh+QQJCgAGACwCAAAADgAKAAADK2hqMRMrLuekCnCU8gqBDCZ2glBcYkSUxIJJgQdaUVDOtAAAAr3oPN/llgAAIfkECQoABgAsBgAAAAoADgAAAytoEdauiz0Yx5BQFTvN2EMXWNgUFETZFIJQdERLiGgZtKohAIDQ7T0RrpEAACH5BAkKAAYALAYAAgAKAA4AAAMqaKoR+609Fie1K4zhZiibNRSg1XAQUXQPIQgE835voQgAIARqh+ummSUBACH5BAUKAAYALAIABgAOAAoAAAMsaLpsES2+F9mEddEgBFbBMGACAAiMOCrlGRBFWBQD2L0dYYjfUuQZEKynSAAAOw==);
113
+ height: 16px;
114
+ width: 16px;
115
+ margin-left: 1em;
116
+ margin-top: 0.2em;
117
+ display: inline-block;
118
+ vertical-align: middle;
119
+ }
120
+
121
+ .ip-geo-block-notice {
122
+ color: #dd3d36;
123
+ }
124
+
125
+ .ip-geo-block-title {
126
+ width: 100px;
127
+ display: inline-block;
128
+ }
129
+
130
+ .ip-geo-block-result {
131
+ color: #2786C2;
132
+ display: inline-block;
133
+ }
134
+
135
+ #ip-geo-block-map {
136
+ height: 400px;
137
+ margin: 1em auto;
138
+ }
139
+
140
+ /* google map infomation window */
141
+ .gm-style-iw {
142
+ width: 18em;
143
+ height: auto !important;
144
+ height: 100%;
145
+ min-height: 100%:
146
+ }
147
+ .gm-style-iw ul {
148
+ margin: 0.1em;
149
+ }
150
+ .gm-style-iw li {
151
+ margin: 0.2em;
152
+ }
153
+
154
+ ul.ip-geo-block-statistics-countries li {
155
+ width: 12em;
156
+ float: left;
157
+ text-align: right;
158
+ padding: 0.2em;
159
+ }
160
+
161
+ /* table */
162
+ table.ip-geo-block-statistics-table {
163
+ float: right;
164
+ }
165
+ table.ip-geo-block-statistics-table th,
166
+ table.ip-geo-block-statistics-table td {
167
+ width: 12em;
168
+ margin: 0;
169
+ padding: 0.2em;
170
+ text-align: right;
171
+ line-height: 1.5em;
172
+ word-wrap: break-word;
173
+ }
174
+ table.ip-geo-block-statistics-table tr:nth-child(even) {
175
+ background-color: #f7f7f7;
176
+ }
177
+ table.ip-geo-block-statistics-table tr:nth-child(odd) {
178
+ }
179
+ table.ip-geo-block-table {
180
+ white-space: normal;
181
+ word-wrap: break-word;
182
+ word-break: break-all;
183
+ }
184
+
185
+ /* for footable */
186
+ .ip-geo-block-log {
187
+ width: 100% !important;
188
+ }
189
+ .ip-geo-block-log * {
190
+ font-size: 13px !important;
191
+ line-height: 1.5em;
192
+ vertical-align: middle;
193
+ }
194
+ .ip-geo-block-log .pagination ul {
195
+ border-radius: 4px;
196
+ display: inline-block;
197
+ margin-bottom: 0;
198
+ margin-left: 0;
199
+ padding-left: 0;
200
+ }
201
+ .ip-geo-block-log .pagination ul > li {
202
+ display: inline;
203
+ }
204
+ .ip-geo-block-log .pagination ul > li:first-child > a,
205
+ .ip-geo-block-log .pagination ul > li:first-child > span {
206
+ border-bottom-left-radius: 4px;
207
+ border-left-width: 1px;
208
+ border-top-left-radius: 4px;
209
+ }
210
+ .ip-geo-block-log .pagination ul > li:last-child > a,
211
+ .ip-geo-block-log .pagination ul > li:last-child > span {
212
+ border-bottom-right-radius: 4px;
213
+ border-top-right-radius: 4px;
214
+ }
215
+ .ip-geo-block-log .pagination ul > .disabled > span,
216
+ .ip-geo-block-log .pagination ul > .disabled > a,
217
+ .ip-geo-block-log .pagination ul > .disabled > a:hover,
218
+ .ip-geo-block-log .pagination ul > .disabled > a:focus {
219
+ background-color: transparent;
220
+ color: #999;
221
+ cursor: default;
222
+ }
223
+ .ip-geo-block-log .pagination ul > li > a,
224
+ .ip-geo-block-log .pagination ul > li > span {
225
+ border-color: #ddd;
226
+ border-image: none;
227
+ border-style: solid;
228
+ border-width: 1px 1px 1px 0;
229
+ float: left;
230
+ line-height: 20px;
231
+ padding: 4px;
232
+ width: 20px;
233
+ text-decoration: none;
234
+ }
235
+ .ip-geo-block-log .pagination ul > .active > a,
236
+ .ip-geo-block-log .pagination ul > .active > span {
237
+ color: #999;
238
+ cursor: default;
239
+ }
240
+ .ip-geo-block-log .pagination ul > li > a:hover,
241
+ .ip-geo-block-log .pagination ul > li > a:focus,
242
+ .ip-geo-block-log .pagination ul > .active > a,
243
+ .ip-geo-block-log .pagination ul > .active > span {
244
+ background-color: #f7f7f7;
245
+ }
246
+ .ip-geo-block-log .pagination-centered {
247
+ text-align: center;
248
+ }
249
+ .ip-geo-block-log.breakpoint > tbody > tr > td > span.footable-toggle {
250
+ font-size: 60% !important;
251
+ position: relative;
252
+ top: -1px;
253
+ left: 2px;
254
+ }
255
+ .ip-geo-block-log > thead > tr > th,
256
+ .ip-geo-block-log > tbody > tr > td {
257
+ padding: 4px 0;
258
+ word-wrap: break-word;
259
+ width: 20%;
260
+ }
261
+ .ip-geo-block-log > thead > tr > th:first-child,
262
+ .ip-geo-block-log > tbody > tr > td:first-child {
263
+ width: 25%;
264
+ }
265
+ .ip-geo-block-log > thead > tr > th:first-child + th,
266
+ .ip-geo-block-log > tbody > tr > td:first-child + td {
267
+ width: 35%;
268
+ }
269
+ .ip-geo-block-log > thead > tr > th:nth-child(5),
270
+ .ip-geo-block-log > tbody > tr > td:nth-child(5),
271
+ .ip-geo-block-log > thead > tr > th:nth-child(5) + th,
272
+ .ip-geo-block-log > tbody > tr > td:nth-child(5) + td {
273
+ width: 60%;
274
+ text-align: left;
275
+ }
276
+ @media screen and (min-width: 1024px) {
277
+ .ip-geo-block-log > thead > tr > th:nth-child(3),
278
+ .ip-geo-block-log > tbody > tr > td:nth-child(3),
279
+ .ip-geo-block-log > thead > tr > th:nth-child(3) + th,
280
+ .ip-geo-block-log > tbody > tr > td:nth-child(3) + td {
281
+ width: 10%;
282
+ }
283
+ }
284
+ .ip-geo-block-log > thead > tr > th > span.footable-sort-indicator {
285
+ color: #888;
286
+ }
287
+ .ip-geo-block-log > tbody > tr > td {
288
+ text-align: center;
289
+ }
290
+ .ip-geo-block-log > tbody > tr > td:first-child {
291
+ text-align: left;
292
+ }
293
+ .ip-geo-block-log .footable-row-detail-row,
294
+ .ip-geo-block-log .footable-row-detail-name,
295
+ .ip-geo-block-log .footable-row-detail-value {
296
+ display: block;
297
+ }
298
+ .ip-geo-block-log .footable-row-detail-value {
299
+ padding: 0 1em 4px 1em;
300
+ white-space: normal;
301
+ word-wrap: break-word;
302
+ word-break: break-all;
303
+ }
304
+ input#ip_geo_block_settings_filter_logs {
305
+ width: 16em;
306
+ padding-top: 3px;
307
+ }
308
+
309
+ /* Scan the country code */
310
+ #ip-geo-block-scan-code {
311
+ vertical-align: middle;
312
+ }
313
+ #ip-geo-block-code-list {
314
+ display: none;
315
+ margin-bottom: 0;
316
+ }
317
+
318
+ /* for google chart */
319
+ #ip-geo-block-countries,
320
+ #ip-geo-block-targets {
321
+ display: none;
322
+ }
323
+ #ip-geo-block-chart-countries {
324
+ height: 200px;
325
+ }
326
+ #ip-geo-block-chart-daily {
327
+ height: 240px;
328
+ }
329
+ #ip_geo_block_settings_validation_plugins,
330
+ #ip_geo_block_settings_validation_themes {
331
+ margin-top: 0.5em;
332
+ }
333
+ #ip-geo-block-toggle-sections,
334
+ #ip-geo-block-back-to-top {
335
+ box-shadow: none;
336
+ }
337
+ #ip-geo-block-decode {
338
+ box-shadow: none;
339
+ text-decoration: none;
340
+ }
341
+ #ip-geo-block-decode:active {
342
+ position: relative;
343
+ top: 1px;
344
+ }
345
+ #ip-geo-block-wp-info textarea {
346
+ margin-top: 0.5em;
347
+ overflow: auto;
348
+ width: 100%;
349
+ word-wrap: normal;
350
+ word-break: normal;
351
+ white-space: pre;
352
+ }
353
+ #ip-geo-block-cycle {
354
+ height: 16px;
355
+ width: 16px;
356
+ margin: 0;
357
+ border: none;
358
+ display: inline-block;
359
+ vertical-align: text-bottom;
360
+ background-size: 16px 16px;
361
+ background-position: center center;
362
+ background-repeat: no-repeat;
363
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAh1BMVEUAda2otLp+rsSHprWHr8IBd7EpfKRGhaNajqeUqrRymKuKoq5yo7prlKgAcqoVe6w8gqQmgq5Tj6wIdqsVdKIshrEMea1Uhp+Anqw0hawDdq4gfKhljqE7hqoLdKYbgbM4jLQygKUGeK8CdawQd6gVeKcad6NKkrSerrZAj7UAc6sAc6rc3NySrVGQAAAALXRSTlP//////////////////////////////////////////////////////////wCl7wv9AAACOklEQVR4Ae2W15rzKgxF9xTZzhTX9B7S/gN6/9ebYqzzGZsw/S7LV3FZgCSIwD/kQ8FVcBU8xatZUczy8luC/ABNOn0DSHEsvyZ4PgLatNCYR3efFxyhTQ8g+qQgJxgv2JefERzJXATRh4LHOUwAHD4S7OGEztRJaN86hAUxtaNWDUf/bRdDBbQMWVDAO8jn89WUhag1MeyCAh6hHofyrliLgZKggDMYgzF3eVAwFq0uCZq5KY0TezjIHDDzC0qqmkwe2ctGDOQVLMkgu+F3/rGXwb4xIPcJ6P3JgkM8wFjmfcFAWfeKQywaAz33BJVuHsUcAt09gVbuLDThAJkdR687ggLmf4gDJLIGV7BydtB8yn3u+fbtuj/LS7G9wZAd1AKK+yxJ1x+aBmibTtgCcEHGHsh0wdbOgNLek4L7lI5BigY8nWuZUQ3qGEXes9JzOKGJztPaGtLslu3lIXJirdxCWkASHGDTMqg7V1DKPplygDG61YJukLHjEErGSXqCSos6xNSOgzP3BDmsQBcchNwkoV8oiNnPA78zIefUgCdJeGIfE7LmFWXsFTCFdzTJ/RlfEMRiSGnFXXbkC7AIeqcKDu4ynseozeouKJiSEYBDwkJyIC1nRUjgblkNWp/e/1vXc2gjoAoLksYgjrrFMi0oDgjEEIDij1scBXMJSH6DAj6RNl7o8MkuLak8Co15/Pk+MRmT0xilQJV/sdWNKg2kTaeroudvNNsDjmejYjSL+e6v2/2r4Cp4BXNajr0H7hRfAAAAAElFTkSuQmCC);
364
+ }
365
+ /* https://developer.wordpress.org/resource/dashicons/ for WordPress 3.8
366
+ #ip-geo-block-cycle:before {
367
+ background: none;
368
+ content: "\f463";
369
+ display: inline-block;
370
+ font: normal 16px/20px dashicons;
371
+ speak: none;
372
+ height: 1em;
373
+ width: 1em;
374
+ text-align: center;
375
+ vertical-align: text-top;
376
+ -webkit-font-smoothing: antialiased;
377
+ -moz-osx-font-smoothing: grayscale;
378
+ }
379
+ */
admin/css/admin.min.css ADDED
@@ -0,0 +1,2 @@
 
 
1
+ /* This stylesheet is used to style the admin option form of the plugin. */
2
+ .ip-geo-block-log .footable-row-detail-value,table.ip-geo-block-table{white-space:normal;word-wrap:break-word;word-break:break-all}#ip-geo-block-scan-code,.ip-geo-block-loading,.ip-geo-block-log *{vertical-align:middle}#ip-geo-block-cycle,.ip-geo-block-loading{background-size:16px 16px;background-position:center center;background-repeat:no-repeat}dfn{cursor:help;border-bottom:1px dotted #888}.form-table{margin:0 1em}fieldset.ip-geo-block-field{border:1px solid #ccc;padding:.35em .625em .75em 1em;margin:1.35em 0 1.5em}fieldset.ip-geo-block-field h2,fieldset.ip-geo-block-field h3{padding:0;margin:0}fieldset.ip-geo-block-field .ip-geo-block-dropdown,fieldset.ip-geo-block-field .ip-geo-block-dropup{cursor:pointer;position:relative;padding-left:1em}fieldset.ip-geo-block-field .ip-geo-block-dropdown:before,fieldset.ip-geo-block-field .ip-geo-block-dropup:before{content:'';height:0;width:0;border:.4em solid transparent;position:absolute}fieldset.ip-geo-block-field .ip-geo-block-dropup:before{border-left:.4em solid #555;left:3px;top:15%}fieldset.ip-geo-block-field .ip-geo-block-dropdown:before{border-top:.4em solid #555;left:0;top:35%}fieldset.ip-geo-block-field ul.ip-geo-block-dropup:before{top:.25em}fieldset.ip-geo-block-field ul.ip-geo-block-dropdown:before{top:.45em}fieldset.ip-geo-block-field .form-table{margin:.5em 0 0}textarea.regular-text{width:25em}ul.ip_geo_block_settings_folding{margin:.5em 0}ul.ip_geo_block_settings_folding ul{margin-bottom:0}ul.ip_geo_block_settings_folding li:first-child{margin-top:.5em}.ip-geo-block-desc,ul.ip-geo-block-list{margin-top:.25em;margin-bottom:.25em}.folding-disable{pointer-events:none;opacity:.5}.folding-inactive{opacity:.5;font-style:oblique!important}.ip-geo-block-hide{display:none}.ip-geo-block-desc,.ip-geo-block-loading,.ip-geo-block-result,.ip-geo-block-sup,.ip-geo-block-title,ul.ip-geo-block-list label{display:inline-block}.ip-geo-block-sup{margin-left:.2em}ul.ip-geo-block-note{list-style:disc;margin-left:1em}@media screen and (min-width:782px){ul.ip-geo-block-list .code{width:15em}}.ip-geo-block-loading{background-image:url(data:image/gif;base64,R0lGODlhEAAQAPIGAAAAAMLCwkJCQpKSkmJiYoKCgv///wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAGACwAAAAAEAAQAAADM2i63P4wyklrC0IEKgAQnAdOmGYFBLExwboQWcG2rlHEwTDQLUsUOd2mBxkUCgNKa+dIAAAh+QQJCgAGACwAAAIACgAOAAADLWgWIqHQCABEVLPe1R4MBOFFRFNsRUNsYDFewTC8iixvQ1EMyxjEvyBLODQkAAAh+QQJCgAGACwAAAAACgAOAAADLWi6IRJrCQCECoU0ag1xxeBARuEQ0UUU5DUM7fK+qTEUYR0EcM3Ev51uB7wAEwAh+QQJCgAGACwAAAAADgAKAAADLWi6URQrLiJEkSaM0eqrkLFtAVEEAgAIylAUQ5SuSqCFNZjhWG3zmB8wOJQkAAAh+QQJCgAGACwCAAAADgAKAAADK2hqMRMrLuekCnCU8gqBDCZ2glBcYkSUxIJJgQdaUVDOtAAAAr3oPN/llgAAIfkECQoABgAsBgAAAAoADgAAAytoEdauiz0Yx5BQFTvN2EMXWNgUFETZFIJQdERLiGgZtKohAIDQ7T0RrpEAACH5BAkKAAYALAYAAgAKAA4AAAMqaKoR+609Fie1K4zhZiibNRSg1XAQUXQPIQgE835voQgAIARqh+ummSUBACH5BAUKAAYALAIABgAOAAoAAAMsaLpsES2+F9mEddEgBFbBMGACAAiMOCrlGRBFWBQD2L0dYYjfUuQZEKynSAAAOw==);height:16px;width:16px;margin-left:1em;margin-top:.2em}.ip-geo-block-notice{color:#dd3d36}.ip-geo-block-title{width:100px}.ip-geo-block-result{color:#2786C2}#ip-geo-block-map{height:400px;margin:1em auto}.gm-style-iw{width:18em;height:auto!important;height:100%;min-height:100%:}.gm-style-iw ul{margin:.1em}.gm-style-iw li{margin:.2em}ul.ip-geo-block-statistics-countries li{width:12em;float:left;text-align:right;padding:.2em}table.ip-geo-block-statistics-table{float:right}table.ip-geo-block-statistics-table td,table.ip-geo-block-statistics-table th{width:12em;margin:0;padding:.2em;text-align:right;line-height:1.5em;word-wrap:break-word}table.ip-geo-block-statistics-table tr:nth-child(even){background-color:#f7f7f7}.ip-geo-block-log{width:100%!important}.ip-geo-block-log *{font-size:13px!important;line-height:1.5em}.ip-geo-block-log .pagination ul{border-radius:4px;display:inline-block;margin-bottom:0;margin-left:0;padding-left:0}.ip-geo-block-log .pagination ul>li{display:inline}.ip-geo-block-log .pagination ul>li:first-child>a,.ip-geo-block-log .pagination ul>li:first-child>span{border-bottom-left-radius:4px;border-left-width:1px;border-top-left-radius:4px}.ip-geo-block-log .pagination ul>li:last-child>a,.ip-geo-block-log .pagination ul>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.ip-geo-block-log .pagination ul>.disabled>a,.ip-geo-block-log .pagination ul>.disabled>a:focus,.ip-geo-block-log .pagination ul>.disabled>a:hover,.ip-geo-block-log .pagination ul>.disabled>span{background-color:transparent;color:#999;cursor:default}.ip-geo-block-log .pagination ul>li>a,.ip-geo-block-log .pagination ul>li>span{border-color:#ddd;border-image:none;border-style:solid;border-width:1px 1px 1px 0;float:left;line-height:20px;padding:4px;width:20px;text-decoration:none}.ip-geo-block-log .pagination ul>.active>a,.ip-geo-block-log .pagination ul>.active>span{color:#999;cursor:default}.ip-geo-block-log .pagination ul>.active>a,.ip-geo-block-log .pagination ul>.active>span,.ip-geo-block-log .pagination ul>li>a:focus,.ip-geo-block-log .pagination ul>li>a:hover{background-color:#f7f7f7}.ip-geo-block-log .pagination-centered{text-align:center}.ip-geo-block-log.breakpoint>tbody>tr>td>span.footable-toggle{font-size:60%!important;position:relative;top:-1px;left:2px}.ip-geo-block-log>tbody>tr>td,.ip-geo-block-log>thead>tr>th{padding:4px 0;word-wrap:break-word;width:20%}.ip-geo-block-log>tbody>tr>td:first-child,.ip-geo-block-log>thead>tr>th:first-child{width:25%}.ip-geo-block-log>tbody>tr>td:first-child+td,.ip-geo-block-log>thead>tr>th:first-child+th{width:35%}.ip-geo-block-log>tbody>tr>td:nth-child(5),.ip-geo-block-log>tbody>tr>td:nth-child(5)+td,.ip-geo-block-log>thead>tr>th:nth-child(5),.ip-geo-block-log>thead>tr>th:nth-child(5)+th{width:60%;text-align:left}@media screen and (min-width:1024px){.ip-geo-block-log>tbody>tr>td:nth-child(3),.ip-geo-block-log>tbody>tr>td:nth-child(3)+td,.ip-geo-block-log>thead>tr>th:nth-child(3),.ip-geo-block-log>thead>tr>th:nth-child(3)+th{width:10%}}.ip-geo-block-log>thead>tr>th>span.footable-sort-indicator{color:#888}.ip-geo-block-log>tbody>tr>td{text-align:center}.ip-geo-block-log>tbody>tr>td:first-child{text-align:left}.ip-geo-block-log .footable-row-detail-name,.ip-geo-block-log .footable-row-detail-row,.ip-geo-block-log .footable-row-detail-value{display:block}.ip-geo-block-log .footable-row-detail-value{padding:0 1em 4px}input#ip_geo_block_settings_filter_logs{width:16em;padding-top:3px}#ip-geo-block-code-list{display:none;margin-bottom:0}#ip-geo-block-countries,#ip-geo-block-targets{display:none}#ip-geo-block-chart-countries{height:200px}#ip-geo-block-chart-daily{height:240px}#ip_geo_block_settings_validation_plugins,#ip_geo_block_settings_validation_themes{margin-top:.5em}#ip-geo-block-back-to-top,#ip-geo-block-toggle-sections{box-shadow:none}#ip-geo-block-decode{box-shadow:none;text-decoration:none}#ip-geo-block-decode:active{position:relative;top:1px}#ip-geo-block-wp-info textarea{margin-top:.5em;overflow:auto;width:100%;word-wrap:normal;word-break:normal;white-space:pre}#ip-geo-block-cycle{height:16px;width:16px;margin:0;border:none;display:inline-block;vertical-align:text-bottom;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAh1BMVEUAda2otLp+rsSHprWHr8IBd7EpfKRGhaNajqeUqrRymKuKoq5yo7prlKgAcqoVe6w8gqQmgq5Tj6wIdqsVdKIshrEMea1Uhp+Anqw0hawDdq4gfKhljqE7hqoLdKYbgbM4jLQygKUGeK8CdawQd6gVeKcad6NKkrSerrZAj7UAc6sAc6rc3NySrVGQAAAALXRSTlP//////////////////////////////////////////////////////////wCl7wv9AAACOklEQVR4Ae2W15rzKgxF9xTZzhTX9B7S/gN6/9ebYqzzGZsw/S7LV3FZgCSIwD/kQ8FVcBU8xatZUczy8luC/ABNOn0DSHEsvyZ4PgLatNCYR3efFxyhTQ8g+qQgJxgv2JefERzJXATRh4LHOUwAHD4S7OGEztRJaN86hAUxtaNWDUf/bRdDBbQMWVDAO8jn89WUhag1MeyCAh6hHofyrliLgZKggDMYgzF3eVAwFq0uCZq5KY0TezjIHDDzC0qqmkwe2ctGDOQVLMkgu+F3/rGXwb4xIPcJ6P3JgkM8wFjmfcFAWfeKQywaAz33BJVuHsUcAt09gVbuLDThAJkdR687ggLmf4gDJLIGV7BydtB8yn3u+fbtuj/LS7G9wZAd1AKK+yxJ1x+aBmibTtgCcEHGHsh0wdbOgNLek4L7lI5BigY8nWuZUQ3qGEXes9JzOKGJztPaGtLslu3lIXJirdxCWkASHGDTMqg7V1DKPplygDG61YJukLHjEErGSXqCSos6xNSOgzP3BDmsQBcchNwkoV8oiNnPA78zIefUgCdJeGIfE7LmFWXsFTCFdzTJ/RlfEMRiSGnFXXbkC7AIeqcKDu4ynseozeouKJiSEYBDwkJyIC1nRUjgblkNWp/e/1vXc2gjoAoLksYgjrrFMi0oDgjEEIDij1scBXMJSH6DAj6RNl7o8MkuLak8Co15/Pk+MRmT0xilQJV/sdWNKg2kTaeroudvNNsDjmejYjSL+e6v2/2r4Cp4BXNajr0H7hRfAAAAAElFTkSuQmCC)}
admin/css/fonts/LICENSE ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ Copyright 2012 Steven Usher & Brad Vincent
2
+
3
+ Released under the MIT license
4
+ You are free to use FooTable in commercial projects as long as this copyright header is left intact.
admin/css/fonts/footable.eot ADDED
Binary file
admin/css/fonts/footable.svg ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
+ <svg xmlns="http://www.w3.org/2000/svg">
4
+ <metadata>
5
+ This is a custom SVG font generated by IcoMoon.
6
+ <iconset grid="16"></iconset>
7
+ </metadata>
8
+ <defs>
9
+ <font id="footable" horiz-adv-x="512" >
10
+ <font-face units-per-em="512" ascent="480" descent="-32" />
11
+ <missing-glyph horiz-adv-x="512" />
12
+ <glyph class="hidden" unicode="&#xf000;" d="M0,480L 512 -32L0 -32 z" horiz-adv-x="0" />
13
+ <glyph unicode="&#xe000;" d="M 496,288L 320,288 L 320,464 c0,8.836-7.164,16-16,16l-96,0 c-8.836,0-16-7.164-16-16l0-176 L 16,288 c-8.836,0-16-7.164-16-16l0-96
14
+ c0-8.836, 7.164-16, 16-16l 176,0 l0-176 c0-8.836, 7.164-16, 16-16l 96,0 c 8.836,0, 16,7.164, 16,16L 320,160 l 176,0 c 8.836,0, 16,7.164, 16,16l0,96
15
+ C 512,280.836, 504.836,288, 496,288z" />
16
+ <glyph unicode="&#xe001;" d="M0,272l0-96 c0-8.836, 7.164-16, 16-16l 480,0 c 8.836,0, 16,7.164, 16,16l0,96 c0,8.836-7.164,16-16,16L 16,288 C 7.164,288,0,280.836,0,272z" />
17
+ <glyph unicode="&#xe002;" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 288,192l0-128 l-64,0 L 224,192 L 96,192 l0,64
18
+ l 128,0 L 224,384 l 64,0 l0-128 l 128,0 l0-64 L 288,192 z" />
19
+ <glyph unicode="&#xe003;" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 416,192L 96,192 l0,64 l 320,0 L 416,192 z" />
20
+ <glyph unicode="&#xe004;" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 256,32
21
+ c-106.039,0-192,85.961-192,192c0,106.039, 85.961,192, 192,192c 106.039,0, 192-85.961, 192-192C 448,117.961, 362.039,32, 256,32zM 384,192 L 288,192 L 288,96 L 224,96 L 224,192 L 128,192 L 128,256 L 224,256 L 224,352 L 288,352 L 288,256 L 384,256 Z" />
22
+ <glyph unicode="&#xe005;" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 256,32
23
+ c-106.039,0-192,85.961-192,192c0,106.039, 85.961,192, 192,192c 106.039,0, 192-85.961, 192-192C 448,117.961, 362.039,32, 256,32zM 128,256L 384,256L 384,192L 128,192z" />
24
+ <glyph unicode="&#xe006;" d="M 256,214.857l0-18.286 q0-4 -2.571-6.571t-6.571-2.571l-64,0 l0-64 q0-4 -2.571-6.571t-6.571-2.571l-18.286,0 q-4,0 -6.571,2.571t-2.571,6.571l0,64 l-64,0 q-4,0 -6.571,2.571t-2.571,6.571l0,18.286 q0,4 2.571,6.571t 6.571,2.571l 64,0 l0,64 q0,4 2.571,6.571t 6.571,2.571l 18.286,0 q 4,0 6.571-2.571t 2.571-6.571l0-64 l 64,0 q 4,0 6.571-2.571t 2.571-6.571zM 292.571,105.143l0,201.143 q0,11.429 -8,19.429t-19.429,8l-201.143,0 q-11.429,0 -19.429-8 t-8-19.429l0-201.143 q0-11.429 8-19.429t 19.429-8l 201.143,0 q 11.429,0 19.429,8t 8,19.429zM 329.143,306.286l0-201.143 q0-26.286 -18.714-45.143t-45.286-18.857l-201.143,0 q-26.571,0 -45.286,18.857t-18.714,45.143l0,201.143 q0,26.571 18.714,45.286t 45.286,18.714l 201.143,0 q 26.571,0 45.286-18.714t 18.714-45.286z" horiz-adv-x="329.143" />
25
+ <glyph unicode="&#xe007;" d="M 265.143,370.286q 26.571,0 45.286-18.714t 18.714-45.286l0-201.143 q0-26.286 -18.714-45.143t-45.286-18.857l-201.143,0 q-26.571,0 -45.286,18.857t-18.714,45.143l0,201.143 q0,26.571 18.714,45.286t 45.286,18.714l 201.143,0 zM 292.571,105.143l0,201.143 q0,11.429 -8,19.429t-19.429,8l-201.143,0 q-11.429,0 -19.429-8t-8-19.429l0-201.143 q0-11.429 8-19.429t 19.429-8l 201.143,0 q 11.429,0 19.429,8t 8,19.429z M 246.857,224q 4,0 6.571-2.571t 2.571-6.571l0-18.286 q0-4 -2.571-6.571t-6.571-2.571l-164.571,0 q-4,0 -6.571,2.571t-2.571,6.571l0,18.286 q0,4 2.571,6.571t 6.571,2.571l 164.571,0 z" horiz-adv-x="329.143" />
26
+ <glyph unicode="&#xe008;" d="M 365.714,205.714l0,36.571 q0,7.429 -5.429,12.857t-12.857,5.429l-91.429,0 l0,91.429 q0,7.429 -5.429,12.857t-12.857,5.429l-36.571,0 q-7.429,0 -12.857-5.429t-5.429-12.857l0-91.429 l-91.429,0 q-7.429,0 -12.857-5.429t-5.429-12.857l0-36.571 q0-7.429 5.429-12.857t 12.857-5.429l 91.429,0 l0-91.429 q0-7.429 5.429-12.857t 12.857-5.429l 36.571,0 q 7.429,0 12.857,5.429t 5.429,12.857l0,91.429 l 91.429,0 q 7.429,0 12.857,5.429t 5.429,12.857zM 438.857,361.143l0-274.286 q0-34 -24.143-58.143t-58.143-24.143l-274.286,0 q-34,0 -58.143,24.143t-24.143,58.143l0,274.286 q0,34 24.143,58.143t 58.143,24.143l 274.286,0 q 34,0 58.143-24.143t 24.143-58.143z" horiz-adv-x="438.857" />
27
+ <glyph unicode="&#xe009;" d="M 365.714,205.714l0,36.571 q0,7.429 -5.429,12.857t-12.857,5.429l-256,0 q-7.429,0 -12.857-5.429t-5.429-12.857l0-36.571 q0-7.429 5.429-12.857t 12.857-5.429l 256,0 q 7.429,0 12.857,5.429t 5.429,12.857zM 438.857,361.143l0-274.286 q0-34 -24.143-58.143t-58.143-24.143l-274.286,0 q-34,0 -58.143,24.143t-24.143,58.143l0,274.286 q0,34 24.143,58.143t 58.143,24.143l 274.286,0 q 34,0 58.143-24.143 t 24.143-58.143z" horiz-adv-x="438.857" />
28
+ <glyph unicode="&#xe00a;" d="M 512,224C 512,82.615, 397.385-32, 256-32s -256,114.615, -256,256s 114.615,256, 256,256S 512,365.385, 512,224z M 233.372,374.628
29
+ l -128-128.001C 99.124,240.379, 96,232.189, 96,224s 3.124-16.379 9.372-22.627c 12.497-12.497 32.759-12.497, 45.256,0L 224,274.745
30
+ L 224,96 c 0-17.673 14.327-32 32-32c 17.673,0, 32,14.327, 32,32l0,178.745 l 73.373-73.373c 12.497-12.497 32.758-12.497, 45.255,0
31
+ c 12.497,12.497, 12.497,32.758, 0,45.254l -128,128.001C 266.131,387.124, 245.869,387.124, 233.372,374.628z" />
32
+ <glyph unicode="&#xe00b;" d="M 512,224C 512,365.385, 397.385,480, 256,480s -256-114.615, -256-256s 114.615-256, 256-256S 512,82.615, 512,224z M 233.372,73.372
33
+ l -128,128.001C 99.124,207.621, 96,215.811, 96,224s 3.124,16.379 9.372,22.627c 12.497,12.497 32.759,12.497, 45.256,0L 224,173.255
34
+ L 224,352 c 0,17.673 14.327,32 32,32c 17.673,0, 32-14.327, 32-32l0-178.745 l 73.373,73.373c 12.497,12.497 32.758,12.497, 45.255,0
35
+ c 12.497-12.497, 12.497-32.758, 0-45.254l -128-128.001C 266.131,60.876, 245.869,60.876, 233.372,73.372z" />
36
+ <glyph unicode="&#xe00c;" d="M 256,480C 397.385,480, 512,365.385, 512,224s -114.615-256, -256-256s -256,114.615, -256,256S 114.615,480, 256,480z M 105.372,201.372
37
+ l 128.001-128C 239.621,67.124, 247.811,64, 256,64s 16.379,3.124 22.627,9.372c 12.497,12.497 12.497,32.759,0,45.256L 205.255,192
38
+ L 384,192 c 17.673,0 32,14.327 32,32c0,17.673, -14.327,32, -32,32l-178.745,0 l 73.373,73.373c 12.497,12.497 12.497,32.758,0,45.255
39
+ c -12.497,12.497, -32.758,12.497, -45.254,0l -128.001-128C 92.876,234.131, 92.876,213.869, 105.372,201.372z" />
40
+ <glyph unicode="&#xe00d;" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 406.628,201.372
41
+ l-128.001-128C 272.379,67.124, 264.189,64, 256,64s-16.379,3.124-22.627,9.372c-12.497,12.497-12.497,32.759,0,45.256L 306.745,192
42
+ L 128,192 c-17.673,0-32,14.327-32,32c0,17.673, 14.327,32, 32,32l 178.745,0 l-73.373,73.373c-12.497,12.497-12.497,32.758,0,45.255
43
+ c 12.497,12.497, 32.758,12.497, 45.254,0l 128.001-128C 419.124,234.131, 419.124,213.869, 406.628,201.372z" />
44
+ <glyph unicode="&#xe00e;" d="M0,160L 96,64L 256,224L 416,64L 512,160L 256.001,416 z" />
45
+ <glyph unicode="&#xe00f;" d="M 512,288L 416,384L 256,224L 96,384L0,288L 256,32.001 z" />
46
+ <glyph unicode="&#xe010;" d="M 320-32L 416,64L 256,224L 416,384L 320,480L 64,224 z" />
47
+ <glyph unicode="&#xe011;" d="M 192,480L 96,384L 256,224L 96,64L 192-32L 448,224 z" />
48
+ <glyph unicode="&#xe012;" d="M 292.571,132.571q0-7.429 -5.429-12.857t-12.857-5.429l-256,0 q-7.429,0 -12.857,5.429t-5.429,12.857t 5.429,12.857l 128,128q 5.429,5.429 12.857,5.429t 12.857-5.429l 128-128q 5.429-5.429 5.429-12.857z" horiz-adv-x="292.571" />
49
+ <glyph unicode="&#xe013;" d="M 292.571,278.857q0-7.429 -5.429-12.857l-128-128q-5.429-5.429 -12.857-5.429t-12.857,5.429l-128,128q-5.429,5.429 -5.429,12.857t 5.429,12.857t 12.857,5.429l 256,0 q 7.429,0 12.857-5.429t 5.429-12.857z" horiz-adv-x="292.571" />
50
+ <glyph unicode="&#xe014;" d="M 182.857,352l0-256 q0-7.429 -5.429-12.857t-12.857-5.429t-12.857,5.429l-128,128q-5.429,5.429 -5.429,12.857t 5.429,12.857l 128,128q 5.429,5.429 12.857,5.429t 12.857-5.429t 5.429-12.857z" horiz-adv-x="182.857" />
51
+ <glyph unicode="&#xe015;" d="M 164.571,224q0-7.429 -5.429-12.857l-128-128q-5.429-5.429 -12.857-5.429t-12.857,5.429t-5.429,12.857l0,256 q0,7.429 5.429,12.857t 12.857,5.429t 12.857-5.429l 128-128q 5.429-5.429 5.429-12.857z" horiz-adv-x="182.857" />
52
+ <glyph unicode="&#xe016;" d="M 256,480L 32-32L 256,64L 480-32 z" />
53
+ <glyph unicode="&#xe017;" d="M 256-32L 480,480L 256,384L 32,480 z" />
54
+ <glyph unicode="&#xe018;" d="M0,224L 512,0L 416,224L 512,448 z" />
55
+ <glyph unicode="&#xe019;" d="M 512,224L0,448L 96,224L0,0 z" />
56
+ <glyph unicode="&#xe01a;" d="M 512,224C 512,82.615, 397.385-32, 256-32s -256,114.615, -256,256s 114.615,256, 256,256S 512,365.385, 512,224z M 48,224
57
+ c 0-114.875 93.125-208 208-208S 464,109.125, 464,224s -93.125,208, -208,208S 48,338.875, 48,224zM 278.627,374.628l 128-128.001c 12.497-12.496 12.497-32.757 0-45.254c -12.497-12.497 -32.758-12.497,-45.255,0L 288,274.745
58
+ L 288,96 c 0-17.673 -14.327-32 -32-32c-17.673,0, -32,14.327, -32,32l0,178.745 l -73.372-73.373c -12.497-12.497 -32.759-12.497,-45.256,0
59
+ C 99.124,207.621, 96,215.811, 96,224s 3.124,16.379, 9.372,22.627l 128,128.001C 245.869,387.124, 266.131,387.124, 278.627,374.628z" />
60
+ <glyph unicode="&#xe01b;" d="M 512,224C 512,365.385, 397.385,480, 256,480s -256-114.615, -256-256s 114.615-256, 256-256S 512,82.615, 512,224z M 48,224
61
+ c 0,114.875 93.125,208 208,208S 464,338.875, 464,224s -93.125-208, -208-208S 48,109.125, 48,224zM 278.627,73.372l 128,128.001c 12.497,12.496 12.497,32.757 0,45.254c -12.497,12.497 -32.758,12.497,-45.255,0L 288,173.255
62
+ L 288,352 c 0,17.673 -14.327,32 -32,32c-17.673,0, -32-14.327, -32-32l0-178.745 l -73.372,73.373c -12.497,12.497 -32.759,12.497,-45.256,0
63
+ C 99.124,240.379, 96,232.189, 96,224s 3.124-16.379, 9.372-22.627l 128-128.001C 245.869,60.876, 266.131,60.876, 278.627,73.372z" />
64
+ <glyph unicode="&#xe01c;" d="M 256,480C 397.385,480, 512,365.385, 512,224s -114.615-256, -256-256s -256,114.615, -256,256S 114.615,480, 256,480z M 256,16
65
+ c 114.875,0 208,93.125 208,208S 370.875,432, 256,432s -208-93.125, -208-208S 141.125,16, 256,16zM 105.372,246.627l 128.001,128c 12.496,12.497 32.757,12.497 45.254,0c 12.497-12.497 12.497-32.758,0-45.255L 205.255,256
66
+ L 384,256 c 17.673,0 32-14.327 32-32c0-17.673, -14.327-32, -32-32l-178.745,0 l 73.373-73.372c 12.497-12.497 12.497-32.759,0-45.256
67
+ C 272.379,67.124, 264.189,64, 256,64s -16.379,3.124, -22.627,9.372l -128.001,128C 92.876,213.869, 92.876,234.131, 105.372,246.627z" />
68
+ <glyph unicode="&#xe01d;" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 256,16
69
+ c-114.875,0-208,93.125-208,208S 141.125,432, 256,432s 208-93.125, 208-208S 370.875,16, 256,16zM 406.628,246.627l-128.001,128c-12.496,12.497-32.757,12.497-45.254,0c-12.497-12.497-12.497-32.758,0-45.255L 306.745,256
70
+ L 128,256 c-17.673,0-32-14.327-32-32c0-17.673, 14.327-32, 32-32l 178.745,0 l-73.373-73.372c-12.497-12.497-12.497-32.759,0-45.256
71
+ C 239.621,67.124, 247.811,64, 256,64s 16.379,3.124, 22.627,9.372l 128.001,128C 419.124,213.869, 419.124,234.131, 406.628,246.627z" />
72
+ <glyph unicode="&#xe01e;" d="M 307.143,141.714q0-3.714 -2.857-6.571l-14.286-14.286q-2.857-2.857 -6.571-2.857t-6.571,2.857l-112.286,112.286l-112.286-112.286q-2.857-2.857 -6.571-2.857t-6.571,2.857l-14.286,14.286q-2.857,2.857 -2.857,6.571t 2.857,6.571l 133.143,133.143q 2.857,2.857 6.571,2.857t 6.571-2.857l 133.143-133.143q 2.857-2.857 2.857-6.571z" horiz-adv-x="329.143" />
73
+ <glyph unicode="&#xe01f;" d="M 307.143,269.714q0-3.714 -2.857-6.571l-133.143-133.143q-2.857-2.857 -6.571-2.857t-6.571,2.857l-133.143,133.143q-2.857,2.857 -2.857,6.571t 2.857,6.571l 14.286,14.286q 2.857,2.857 6.571,2.857t 6.571-2.857l 112.286-112.286l 112.286,112.286q 2.857,2.857 6.571,2.857t 6.571-2.857l 14.286-14.286q 2.857-2.857 2.857-6.571z" horiz-adv-x="329.143" />
74
+ <glyph unicode="&#xe020;" d="M 179.143,324.571q0-3.714 -2.857-6.571l-112.286-112.286l 112.286-112.286q 2.857-2.857 2.857-6.571t-2.857-6.571l-14.286-14.286q-2.857-2.857 -6.571-2.857t-6.571,2.857l-133.143,133.143q-2.857,2.857 -2.857,6.571t 2.857,6.571l 133.143,133.143q 2.857,2.857 6.571,2.857t 6.571-2.857l 14.286-14.286q 2.857-2.857 2.857-6.571z" horiz-adv-x="182.857" />
75
+ <glyph unicode="&#xe021;" d="M 170,205.714q0-3.714 -2.857-6.571l-133.143-133.143q-2.857-2.857 -6.571-2.857t-6.571,2.857l-14.286,14.286q-2.857,2.857 -2.857,6.571t 2.857,6.571l 112.286,112.286l-112.286,112.286q-2.857,2.857 -2.857,6.571t 2.857,6.571l 14.286,14.286q 2.857,2.857 6.571,2.857t 6.571-2.857l 133.143-133.143q 2.857-2.857 2.857-6.571z" horiz-adv-x="182.857" />
76
+ <glyph unicode="&#xe022;" d="M 292.571,169.143q0-7.429 -5.429-12.857l-128-128q-5.429-5.429 -12.857-5.429t-12.857,5.429l-128,128q-5.429,5.429 -5.429,12.857t 5.429,12.857t 12.857,5.429l 256,0 q 7.429,0 12.857-5.429t 5.429-12.857zM 292.571,278.857q0-7.429 -5.429-12.857t-12.857-5.429l-256,0 q-7.429,0 -12.857,5.429t-5.429,12.857t 5.429,12.857l 128,128q 5.429,5.429 12.857,5.429t 12.857-5.429l 128-128q 5.429-5.429 5.429-12.857z" horiz-adv-x="292.571" />
77
+ <glyph unicode="&#x20;" horiz-adv-x="256" />
78
+ </font></defs></svg>
admin/css/fonts/footable.ttf ADDED
Binary file
admin/css/fonts/footable.woff ADDED
Binary file
admin/css/footable.core.min.css ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * FooTable - Awesome Responsive Tables
3
+ * Version : 2.0.3
4
+ * http://fooplugins.com/plugins/footable-jquery/
5
+ *
6
+ * Copyright 2014 Steven Usher & Brad Vincent
7
+ * Released under the MIT license
8
+ * You are free to use FooTable in commercial projects as long as this copyright header is left intact.
9
+ */
10
+ @font-face{font-family:'footable';src:url('fonts/footable.eot');src:url('fonts/footable.eot?#iefix') format('embedded-opentype'),url('fonts/footable.woff') format('woff'),url('fonts/footable.ttf') format('truetype'),url('fonts/footable.svg#footable') format('svg');font-weight:normal;font-style:normal}@media screen and (-webkit-min-device-pixel-ratio:0){@font-face{font-family:'footable';src:url('fonts/footable.svg#footable') format('svg');font-weight:normal;font-style:normal}}.footable{width:100%}.footable.breakpoint>tbody>tr.footable-detail-show>td{border-bottom:0}.footable.breakpoint>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e001"}.footable.breakpoint>tbody>tr:hover:not(.footable-row-detail){cursor:pointer}.footable.breakpoint>tbody>tr>td.footable-cell-detail{background:#eee;border-top:0}.footable.breakpoint>tbody>tr>td>span.footable-toggle{display:inline-block;font-family:'footable';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;padding-right:5px;font-size:14px;color:#888}.footable.breakpoint>tbody>tr>td>span.footable-toggle:before{content:"\e000"}.footable.breakpoint.toggle-circle>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e005"}.footable.breakpoint.toggle-circle>tbody>tr>td>span.footable-toggle:before{content:"\e004"}.footable.breakpoint.toggle-circle-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e003"}.footable.breakpoint.toggle-circle-filled>tbody>tr>td>span.footable-toggle:before{content:"\e002"}.footable.breakpoint.toggle-square>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e007"}.footable.breakpoint.toggle-square>tbody>tr>td>span.footable-toggle:before{content:"\e006"}.footable.breakpoint.toggle-square-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e009"}.footable.breakpoint.toggle-square-filled>tbody>tr>td>span.footable-toggle:before{content:"\e008"}.footable.breakpoint.toggle-arrow>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e00f"}.footable.breakpoint.toggle-arrow>tbody>tr>td>span.footable-toggle:before{content:"\e011"}.footable.breakpoint.toggle-arrow-small>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e013"}.footable.breakpoint.toggle-arrow-small>tbody>tr>td>span.footable-toggle:before{content:"\e015"}.footable.breakpoint.toggle-arrow-circle>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e01b"}.footable.breakpoint.toggle-arrow-circle>tbody>tr>td>span.footable-toggle:before{content:"\e01d"}.footable.breakpoint.toggle-arrow-circle-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e00b"}.footable.breakpoint.toggle-arrow-circle-filled>tbody>tr>td>span.footable-toggle:before{content:"\e00d"}.footable.breakpoint.toggle-arrow-tiny>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e01f"}.footable.breakpoint.toggle-arrow-tiny>tbody>tr>td>span.footable-toggle:before{content:"\e021"}.footable.breakpoint.toggle-arrow-alt>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e017"}.footable.breakpoint.toggle-arrow-alt>tbody>tr>td>span.footable-toggle:before{content:"\e019"}.footable.breakpoint.toggle-medium>tbody>tr>td>span.footable-toggle{font-size:18px}.footable.breakpoint.toggle-large>tbody>tr>td>span.footable-toggle{font-size:24px}.footable>thead>tr>th{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none}.footable>thead>tr>th.footable-sortable:hover{cursor:pointer}.footable>thead>tr>th.footable-sorted>span.footable-sort-indicator:before{content:"\e013"}.footable>thead>tr>th.footable-sorted-desc>span.footable-sort-indicator:before{content:"\e012"}.footable>thead>tr>th>span.footable-sort-indicator{display:inline-block;font-family:'footable';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;padding-left:5px}.footable>thead>tr>th>span.footable-sort-indicator:before{content:"\e022"}.footable>tfoot .pagination{margin:0}.footable.no-paging .hide-if-no-paging{display:none}.footable-row-detail-inner{display:table}.footable-row-detail-row{display:table-row;line-height:1.5em}.footable-row-detail-group{display:block;line-height:2em;font-size:1.2em;font-weight:bold}.footable-row-detail-name{display:table-cell;font-weight:bold;padding-right:.5em}.footable-row-detail-value{display:table-cell}.footable-odd{background-color:#f7f7f7}
admin/includes/class-admin-ajax.php ADDED
@@ -0,0 +1,486 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class IP_Geo_Block_Admin_Ajax {
3
+
4
+ /**
5
+ * Admin ajax sub functions
6
+ *
7
+ */
8
+ static public function search_ip( $which ) {
9
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-lkup.php';
10
+
11
+ // check format
12
+ if ( filter_var( $ip = $_POST['ip'], FILTER_VALIDATE_IP ) ) {
13
+ // get option settings and compose request headers
14
+ $options = IP_Geo_Block::get_option();
15
+ $args = IP_Geo_Block::get_request_headers( $options );
16
+
17
+ // create object for provider and get location
18
+ if ( $geo = IP_Geo_Block_API::get_instance( $which, $options ) )
19
+ $res = $geo->get_location( $ip, $args );
20
+ else
21
+ $res = array( 'errorMessage' => 'Unknown service.' );
22
+ }
23
+
24
+ else {
25
+ $res = array( 'errorMessage' => 'Invalid IP address.' );
26
+ }
27
+
28
+ if ( empty( $res['errorMessage'] ) )
29
+ $res['host'] = IP_Geo_Block_Lkup::gethostbyaddr( $ip );
30
+
31
+ return $res;
32
+ }
33
+
34
+ /**
35
+ * Get country code from providers
36
+ *
37
+ */
38
+ static public function scan_country() {
39
+ // scan all the country code using selected APIs
40
+ $ip = IP_Geo_Block::get_ip_address();
41
+ $options = IP_Geo_Block::get_option();
42
+ $args = IP_Geo_Block::get_request_headers( $options );
43
+ $type = IP_Geo_Block_Provider::get_providers( 'type', FALSE, FALSE );
44
+ $providers = IP_Geo_Block_Provider::get_valid_providers( $options['providers'], FALSE, FALSE );
45
+
46
+ $res['IP address'] = esc_html( $ip );
47
+
48
+ foreach ( $providers as $provider ) {
49
+ if ( $geo = IP_Geo_Block_API::get_instance( $provider, $options ) ) {
50
+ $ret = $geo->get_location( $ip, $args );
51
+ $res[ $provider ] = array(
52
+ 'type' => $type[ $provider ],
53
+ 'code' => esc_html(
54
+ FALSE === $ret ? __( 'n/a', 'ip-geo-block' ) : (
55
+ ! empty( $ret['errorMessage'] ) ? $ret['errorMessage'] : (
56
+ ! empty( $ret['countryCode' ] ) ? $ret['countryCode' ] :
57
+ __( 'UNKNOWN', 'ip-geo-block' ) ) )
58
+ ),
59
+ );
60
+ }
61
+ }
62
+
63
+ return $res;
64
+ }
65
+
66
+ /**
67
+ * Insert array
68
+ *
69
+ */
70
+ static private function array_insert( &$base_array, $insert_value, $position = null ) {
71
+ if ( ! is_array( $insert_value ) )
72
+ $insert_value = array( $insert_value );
73
+
74
+ $position = is_null( $position ) ? count( $base_array ) : intval( $position );
75
+
76
+ $base_array = array_merge(
77
+ array_splice( $base_array, 0, $position ),
78
+ $insert_value, $base_array
79
+ );
80
+ }
81
+
82
+ /**
83
+ * Export logs from MySQL DB
84
+ *
85
+ */
86
+ static public function export_logs( $which ) {
87
+ $csv = '';
88
+ $which = IP_Geo_Block_Logs::restore_logs( $which );
89
+ $date = isset( $which[0] ) ? $which[0][1] : $_SERVER['REQUEST_TIME'];
90
+ $date = IP_Geo_Block_Util::localdate( $date, 'Y-m-d_H-i-s' );
91
+
92
+ foreach ( $which as $data ) {
93
+ $hook = array_shift( $data );
94
+ self::array_insert( $data, $hook, 3 );
95
+ $data[0] = IP_Geo_Block_Util::localdate( $data[0], 'Y-m-d H:i:s' );
96
+ $csv .= implode( ',', $data ) . PHP_EOL;
97
+ }
98
+
99
+ // Send as file
100
+ header( 'Content-Description: File Transfer' );
101
+ header( 'Content-Type: application/octet-stream' );
102
+ header( 'Content-Disposition: attachment; filename="' . IP_Geo_Block::PLUGIN_NAME . '_' . $date . '.csv"' );
103
+ header( 'Pragma: public' );
104
+ header( 'Expires: 0' );
105
+ header( 'Cache-Control: no-store, no-cache, must-revalidate' );
106
+ header( 'Content-Length: ' . strlen( $csv ) );
107
+ echo $csv;
108
+ }
109
+
110
+ /**
111
+ * Restore logs from MySQL DB
112
+ *
113
+ */
114
+ static public function restore_logs( $which ) {
115
+ // if js is slow then limit the number of rows
116
+ $list = array();
117
+ $limit = IP_Geo_Block_Logs::limit_rows( @$_POST['time'] );
118
+
119
+ foreach ( IP_Geo_Block_Logs::restore_logs( $which ) as $row ) {
120
+ $hook = array_shift( $row );
121
+ $list[ $hook ][] = $row; // array_map( 'IP_Geo_Block_Logs::validate_utf8', $row );
122
+ }
123
+
124
+ // compose html with sanitization
125
+ foreach ( $list as $hook => $rows ) {
126
+ $html = '';
127
+ $n = 0;
128
+
129
+ foreach ( $rows as $row ) {
130
+ $log = (int)array_shift( $row );
131
+ $html .= '<tr><td data-value='.$log.'>';
132
+ $html .= IP_Geo_Block_Util::localdate( $log, 'Y-m-d H:i:s' ) . "</td>";
133
+
134
+ $log = array_shift( $row );
135
+ $html .= '<td><a href="#!">' . esc_html( $log ) . '</a></td>';
136
+
137
+ foreach ( $row as $log ) {
138
+ $html .= '<td>' . esc_html( $log ) . '</td>';
139
+ }
140
+
141
+ $html .= "</tr>";
142
+ if ( ++$n >= $limit ) break;
143
+ }
144
+
145
+ $res[ $hook ] = $html;
146
+ }
147
+
148
+ return isset( $res ) ? $res : NULL;
149
+ }
150
+
151
+ /**
152
+ * Validate json from the client and respond safe data
153
+ *
154
+ */
155
+ static public function validate_settings( $parent ) {
156
+ // restore escaped characters (see wp_magic_quotes() in wp-includes/load.php)
157
+ $json = str_replace(
158
+ array( '\\"', '\\\\', "'" ),
159
+ array( '"', '\\', '\"' ),
160
+ isset( $_POST['data'] ) ? $_POST['data'] : ''
161
+ );
162
+
163
+ if ( NULL === ( $data = json_decode( $json, TRUE ) ) )
164
+ wp_die( 'Illegal JSON format.', '', array( 'response' => 500, 'back_link' => TRUE ) ); // @Since 2.0.4
165
+
166
+ // Sanitize to fit the type of each field
167
+ $temp = self::json_to_settings( $data );
168
+
169
+ // Integrate posted data into current settings because if can be a part of hole data
170
+ unset( $temp['version'] );
171
+ $temp = array_replace_recursive( IP_Geo_Block::get_option(), $temp );
172
+
173
+ // Validate options and convert to json
174
+ $temp = $parent->validate_options( $temp );
175
+ $data = self::settings_to_json( $temp );
176
+ $json = self::json_unsafe_encode( $data );
177
+
178
+ mbstring_binary_safe_encoding(); // @since 3.7.0
179
+ $length = strlen( $json );
180
+ reset_mbstring_encoding(); // @since 3.7.0
181
+
182
+ // Send json as file
183
+ header( 'Content-Description: File Transfer' );
184
+ header( 'Content-Type: application/octet-stream' );
185
+ header( 'Content-Disposition: attachment; filename="' . IP_Geo_Block::PLUGIN_NAME . '-settings.json"' );
186
+ header( 'Pragma: public' );
187
+ header( 'Expires: 0' );
188
+ header( 'Cache-Control: no-store, no-cache, must-revalidate' );
189
+ header( 'Content-Length: ' . $length );
190
+ echo $json;
191
+ }
192
+
193
+ /**
194
+ * Convert json associative array to settings array
195
+ *
196
+ */
197
+ static private function json_to_settings( $input ) {
198
+ $settings = array();
199
+ $prfx = IP_Geo_Block::OPTION_NAME;
200
+
201
+ foreach ( $input as $key => $val ) {
202
+ if ( preg_match( "/${prfx}\[(.+?)\](?:\[(.+?)\](?:\[(.+?)\])?)?/", $key, $m ) ) {
203
+ switch ( count( $m ) ) {
204
+ case 2:
205
+ $settings[ $m[1] ] = $val;
206
+ break;
207
+
208
+ case 3:
209
+ $settings[ $m[1] ][ $m[2] ] = $val;
210
+ break;
211
+
212
+ case 4:
213
+ if ( is_numeric( $m[3] ) ) {
214
+ if ( empty( $settings[ $m[1] ][ $m[2] ] ) )
215
+ $settings[ $m[1] ][ $m[2] ] = 0;
216
+ $settings[ $m[1] ][ $m[2] ] |= $val;
217
+ } else {
218
+ $settings[ $m[1] ][ $m[2] ][ $m[3] ] = $val;
219
+ }
220
+ break;
221
+ }
222
+ }
223
+ }
224
+
225
+ return $settings;
226
+ }
227
+
228
+ /**
229
+ * Convert settings array to json associative array
230
+ *
231
+ */
232
+ static public function settings_to_json( $input, $overwrite = TRUE ) {
233
+ $keys = array(
234
+ '[version]',
235
+ '[matching_rule]',
236
+ '[white_list]',
237
+ '[black_list]',
238
+ '[extra_ips][white_list]',
239
+ '[extra_ips][black_list]',
240
+ '[signature]',
241
+ '[login_fails]',
242
+ '[response_code]',
243
+ '[response_msg]', // 3.0.0
244
+ '[redirect_uri]', // 3.0.0
245
+ '[validation][timing]', // 2.2.9
246
+ '[validation][proxy]',
247
+ '[validation][comment]',
248
+ '[validation][xmlrpc]',
249
+ '[validation][login]',
250
+ '[login_action][login]', // 2.2.8
251
+ '[login_action][register]', // 2.2.8
252
+ '[login_action][resetpasss]', // 2.2.8
253
+ '[login_action][lostpassword]', // 2.2.8
254
+ '[login_action][postpass]', // 2.2.8
255
+ '[validation][admin][1]',
256
+ '[validation][admin][2]',
257
+ '[validation][ajax][1]',
258
+ '[validation][ajax][2]',
259
+ '[validation][plugins]',
260
+ '[validation][themes]',
261
+ '[validation][includes]', // 3.0.0
262
+ '[validation][uploads]', // 3.0.0
263
+ '[validation][languages]', // 3.0.0
264
+ '[validation][public]', // 3.0.0
265
+ '[rewrite][plugins]',
266
+ '[rewrite][themes]',
267
+ '[rewrite][includes]', // 3.0.0
268
+ '[rewrite][uploads]', // 3.0.0
269
+ '[rewrite][languages]', // 3.0.0
270
+ '[exception][plugins][*]', // 2.2.5
271
+ '[exception][themes][*]', // 2.2.5
272
+ '[exception][admin][$]', // 3.0.0
273
+ '[exception][public][$]', // 3.0.0
274
+ '[exception][includes][$]', // 3.0.0
275
+ '[exception][uploads][$]', // 3.0.0
276
+ '[exception][languages][$]', // 3.0.0
277
+ '[public][matching_rule]', // 3.0.0
278
+ '[public][white_list]', // 3.0.0
279
+ '[public][black_list]', // 3.0.0
280
+ '[public][target_rule]', // 3.0.0
281
+ '[public][target_pages][$]', // 3.0.0
282
+ '[public][target_posts][$]', // 3.0.0
283
+ '[public][target_cates][$]', // 3.0.0
284
+ '[public][target_tags][$]', // 3.0.0
285
+ '[public][ua_list]', // 3.0.0
286
+ '[public][simulate]', // 3.0.0
287
+ '[providers][Maxmind]',
288
+ '[providers][IP2Location]',
289
+ '[providers][freegeoip.net]',
290
+ '[providers][ipinfo.io]',
291
+ '[providers][IP-Json]',
292
+ '[providers][Nekudo]',
293
+ '[providers][Xhanch]',
294
+ '[providers][GeoIPLookup]', // 2.2.8
295
+ '[providers][ip-api.com]',
296
+ '[providers][IPInfoDB]',
297
+ '[save_statistics]',
298
+ '[validation][reclogs]',
299
+ '[validation][recdays]', // 2.2.9
300
+ '[validation][maxlogs]',
301
+ '[validation][postkey]',
302
+ '[update][auto]',
303
+ '[anonymize]',
304
+ '[cache_time_gc]', // 3.0.0
305
+ '[cache_hold]',
306
+ '[cache_time]',
307
+ '[comment][pos]',
308
+ '[comment][msg]',
309
+ '[clean_uninstall]',
310
+ '[api_key][GoogleMap]', // 2.2.7
311
+ '[network_wide]', // 3.0.0
312
+ );
313
+ $json = array();
314
+ $prfx = IP_Geo_Block::OPTION_NAME;
315
+
316
+ foreach ( $keys as $key ) {
317
+ if ( preg_match( "/\[(.+?)\](?:\[(.+?)\](?:\[(.+?)\])?)?/", $key, $m ) ) {
318
+ switch ( count( $m ) ) {
319
+ case 2:
320
+ if ( isset( $input[ $m[1] ] ) ) {
321
+ $json[ $prfx.'['.$m[1].']' ] = strval( $input[ $m[1] ] );
322
+ }
323
+ break;
324
+
325
+ case 3:
326
+ if ( !@is_null( $input[ $m[1] ][ $m[2] ] ) || $overwrite ) {
327
+ $json[ $prfx.'['.$m[1].']['.$m[2].']' ] = (
328
+ isset( $input[ $m[1] ][ $m[2] ] ) &&
329
+ '@' !== $input[ $m[1] ][ $m[2] ] ?
330
+ strval( $input[ $m[1] ][ $m[2] ] ) : ''
331
+ );
332
+ }
333
+ break;
334
+
335
+ case 4:
336
+ if ( is_numeric( $m[3] ) ) {
337
+ if ( isset( $input[ $m[1] ][ $m[2] ] ) )
338
+ $json[ $prfx.'['.$m[1].']['.$m[2].']'.'['.$m[3].']' ] =
339
+ strval( $input[ $m[1] ][ $m[2] ] ) & (int)$m[3];
340
+ }
341
+ elseif ( isset( $input[ $m[1] ][ $m[2] ] ) ) {
342
+ if ( '*' === $m[3] ) {
343
+ foreach ( $input[ $m[1] ][ $m[2] ] as $val ) {
344
+ $json[ $prfx.'['.$m[1].']['.$m[2].']'.'['.$val.']' ] = 1;
345
+ }
346
+ } elseif ( is_array( $input[ $m[1] ][ $m[2] ] ) ) {
347
+ $json[ $prfx.'['.$m[1].']['.$m[2].']' ] = implode( ',', $input[ $m[1] ][ $m[2] ] );
348
+ }
349
+ }
350
+ break;
351
+ }
352
+ }
353
+ }
354
+
355
+ return $json;
356
+ }
357
+
358
+ /**
359
+ * Make preferred settings with formatted json
360
+ *
361
+ */
362
+ static public function preferred_to_json() {
363
+ return self::settings_to_json(
364
+ array(
365
+ 'validation' => array( // Action hook for validation
366
+ 'comment' => TRUE, // Validate on comment post
367
+ 'login' => 1, // Validate on login
368
+ 'admin' => 3, // Validate on admin (1:country 2:ZEP)
369
+ 'ajax' => 3, // Validate on ajax/post (1:country 2:ZEP)
370
+ 'xmlrpc' => 1, // Validate on xmlrpc (1:country 2:close)
371
+ 'postkey' => 'action,comment,log,pwd', // Keys in $_POST
372
+ 'plugins' => 2, // Validate on wp-content/plugins
373
+ 'themes' => 2, // Validate on wp-content/themes
374
+ 'timing' => 1, // 0:init, 1:mu-plugins, 2:drop-in
375
+ ),
376
+ 'signature' => "../,/wp-config.php,/passwd\ncurl,wget,eval,base64\nselect:.5,where:.5,union:.5\nload_file:.5,create:.6,password:.4",
377
+ 'rewrite' => array( // Apply rewrite rule
378
+ 'plugins' => TRUE, // for wp-content/plugins
379
+ 'themes' => TRUE, // for wp-content/themes
380
+ ),
381
+ ),
382
+ FALSE // should not overwrite the existing parameters
383
+ );
384
+ }
385
+
386
+ // Encode json without JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT
387
+ // Note: It should not be rendered via jQuery .html() at client side
388
+ static private function json_unsafe_encode( $data ) {
389
+ if ( version_compare( PHP_VERSION, '5.4', '>=' ) ) {
390
+ $opts = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
391
+ if ( function_exists( 'wp_json_encode' ) ) // @since 4.1.0
392
+ $json = wp_json_encode( $data, $opts );
393
+ else
394
+ $json = json_encode( $data, $opts );
395
+ }
396
+
397
+ else { // JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES are not supported in PHP 5.3 and under
398
+ $json = self::json_unescaped_unicode( $data );
399
+ $json = preg_replace(
400
+ array( '!{"!', '!":!', '!("?),"!', '!"}!', '!\\\\/!' ),
401
+ array( '{'.PHP_EOL.' "', '": ', '$1,'.PHP_EOL.' "', '"'.PHP_EOL.'}', '/' ),
402
+ $json
403
+ );
404
+ }
405
+
406
+ return $json;
407
+ }
408
+
409
+ // Fallback function for PHP 5.3 and under
410
+ // @link http://qiita.com/keromichan16/items/5ff45a77fb0d48e046cc
411
+ // @link http://stackoverflow.com/questions/16498286/why-does-the-php-json-encode-function-convert-utf-8-strings-to-hexadecimal-entit/
412
+ static private function json_unescaped_unicode( $input ) {
413
+ return preg_replace_callback(
414
+ '/(?:\\\\u[0-9a-zA-Z]{4})++/',
415
+ array( __CLASS__, 'convert_encoding' ),
416
+ json_encode( $input )
417
+ );
418
+ }
419
+
420
+ // Fallback function for PHP 5.3 and under
421
+ static private function convert_encoding( $matches ) {
422
+ return mb_convert_encoding(
423
+ pack( 'H*', str_replace( '\\u', '', $matches[0] ) ), 'UTF-8', 'UTF-16'
424
+ );
425
+ }
426
+
427
+ static public function get_wp_info() {
428
+ // PHP, WordPress
429
+ $res = array();
430
+ $res[] = array( 'PHP' => PHP_VERSION );
431
+ $res[] = array( 'BC Math' => (extension_loaded('gmp') ? 'gmp ' : '') . (function_exists('bcadd') ? 'yes' : 'no') );
432
+ $res[] = array( 'mb_strcut' => function_exists( 'mb_strcut' ) ? 'yes' : 'no' );
433
+ $res[] = array( 'WordPress' => $GLOBALS['wp_version'] );
434
+ $res[] = array( 'Multisite' => is_multisite() ? 'yes' : 'no' );
435
+
436
+ // Child and parent themes
437
+ $activated = wp_get_theme(); // @since 3.4.0
438
+ $res[] = array( esc_html( $activated->get( 'Name' ) ) => esc_html( $activated->get( 'Version' ) ) );
439
+
440
+ if ( $installed = $activated->get( 'Template' ) ) {
441
+ $activated = wp_get_theme( $installed );
442
+ $res[] = array( esc_html( $activated->get( 'Name' ) ) => esc_html( $activated->get( 'Version' ) ) );
443
+ }
444
+
445
+ // Plugins
446
+ $installed = get_plugins(); // @since 1.5.0
447
+ $activated = get_site_option( 'active_sitewide_plugins' ); // @since 2.8.0
448
+ ! is_array( $activated ) and $activated = array();
449
+ $activated = array_merge( $activated, array_fill_keys( get_option( 'active_plugins' ), TRUE ) );
450
+
451
+ foreach ( $installed as $key => $val ) {
452
+ if ( isset( $activated[ $key ] ) ) {
453
+ $res[] = array(
454
+ esc_html( $val['Name'] ) => esc_html( $val['Version'] )
455
+ );
456
+ }
457
+ }
458
+
459
+ // Logs (hook, time, ip, code, result, method, user_agent, headers, data)
460
+ $installed = IP_Geo_Block_Logs::search_logs( IP_Geo_Block::get_ip_address() );
461
+
462
+ foreach ( array_reverse( $installed ) as $val ) {
463
+ // hide port and nonce
464
+ $method = preg_replace( '/\[\d+\]/', '', $val['method'] );
465
+ $method = preg_replace( '/(' . IP_Geo_Block::PLUGIN_NAME . '-auth-nonce)(?:=|%3D)([\w]+)/', '$1=...', $method );
466
+
467
+ // add post data
468
+ $query = array();
469
+ foreach ( explode( ',', $val['data'] ) as $str ) {
470
+ if ( FALSE !== strpos( $str, '=' ) )
471
+ $query[] = $str;
472
+ }
473
+
474
+ if ( ! empty( $query ) )
475
+ $method .= '(' . implode( ',', $query ) . ')';
476
+
477
+ $res[] = array(
478
+ esc_html( IP_Geo_Block_Util::localdate( $val['time'], 'Y-m-d H:i:s' ) ) =>
479
+ esc_html( str_pad( $val['result'], 8 ) . $method )
480
+ );
481
+ }
482
+
483
+ return $res;
484
+ }
485
+
486
+ }
admin/includes/class-admin-rewrite.php ADDED
@@ -0,0 +1,340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class IP_Geo_Block_Admin_Rewrite {
3
+
4
+ /**
5
+ * Instance of this class.
6
+ */
7
+ protected static $instance = NULL;
8
+
9
+ // private values
10
+ private $doc_root = NULL; // document root
11
+ private $base_uri = NULL; // plugins base uri
12
+ private $wp_dirs = array();
13
+
14
+ // template of rewrite rule in wp-content/(plugins|themes)/
15
+ private $rewrite_rule = array(
16
+ 'apache' => array(
17
+ 'plugins' => array(
18
+ '# BEGIN IP Geo Block',
19
+ '<IfModule mod_rewrite.c>',
20
+ 'RewriteEngine on',
21
+ 'RewriteBase %REWRITE_BASE%',
22
+ 'RewriteCond %{REQUEST_URI} !ip-geo-block/rewrite.php$',
23
+ 'RewriteRule ^.*\.php$ rewrite.php [L]',
24
+ '</IfModule>',
25
+ '# END IP Geo Block',
26
+ ),
27
+ 'themes' => array(
28
+ '# BEGIN IP Geo Block',
29
+ '<IfModule mod_rewrite.c>',
30
+ 'RewriteEngine on',
31
+ 'RewriteBase %REWRITE_BASE%',
32
+ 'RewriteRule ^.*\.php$ rewrite.php [L]',
33
+ '</IfModule>',
34
+ '# END IP Geo Block',
35
+ ),
36
+ ),
37
+ 'nginx' => array(
38
+ 'plugins' => array(
39
+ '# BEGIN IP Geo Block',
40
+ 'location ~ %REWRITE_BASE%rewrite.php$ {}',
41
+ 'location %WP_CONTENT_DIR%/plugins/ {',
42
+ ' rewrite ^%WP_CONTENT_DIR%/plugins/.*/.*\.php$ %REWRITE_BASE%rewrite.php break;',
43
+ '}',
44
+ '# END IP Geo Block',
45
+ ),
46
+ 'themes' => array(
47
+ '# BEGIN IP Geo Block',
48
+ 'location %WP_CONTENT_DIR%/themes/ {',
49
+ ' rewrite ^%WP_CONTENT_DIR%/themes/.*/.*\.php$ %REWRITE_BASE%rewrite.php break;',
50
+ '}',
51
+ '# END IP Geo Block',
52
+ ),
53
+ ),
54
+ );
55
+
56
+ public function __construct() {
57
+ // http://stackoverflow.com/questions/25017381/setting-php-document-root-on-webserver
58
+ $this->doc_root = str_replace( $_SERVER['SCRIPT_NAME'], '', $_SERVER['SCRIPT_FILENAME'] );
59
+ $this->base_uri = str_replace( $this->doc_root, '', IP_GEO_BLOCK_PATH );
60
+
61
+ // target directories
62
+ $condir = str_replace( $this->doc_root, '', WP_CONTENT_DIR );
63
+ $this->wp_dirs = array(
64
+ 'plugins' => $condir . '/plugins/',
65
+ 'themes' => $condir . '/themes/',
66
+ );
67
+ }
68
+
69
+ /**
70
+ * Return an instance of this class.
71
+ *
72
+ */
73
+ private static function get_instance() {
74
+ return self::$instance ? self::$instance : ( self::$instance = new self );
75
+ }
76
+
77
+ /**
78
+ * Get type of server
79
+ *
80
+ * @return string 'apache', 'nginx' or NULL
81
+ */
82
+ private function get_server_type() {
83
+ global $is_apache, $is_nginx; // wp-includes/vars.php
84
+ return $is_apache ? 'apache' : ( $is_nginx ? 'nginx' : NULL );
85
+ }
86
+
87
+ /**
88
+ * Extract the block of rewrite rule
89
+ *
90
+ * @param array contents of configuration file
91
+ * @return array list of begin and end
92
+ */
93
+ private function find_rewrite_block( $content ) {
94
+ return preg_grep(
95
+ '/^\s*?#\s*?(BEGIN|END)?\s*?IP Geo Block\s*?(BEGIN|END)?\s*?$/i',
96
+ $content
97
+ );
98
+ }
99
+
100
+ /**
101
+ * Get the path of .htaccess in wp-content/plugins/themes/
102
+ *
103
+ * @param string 'plugins' or 'themes'
104
+ * @return string absolute path to the .htaccess
105
+ */
106
+ private function get_rewrite_file( $which ) {
107
+ global $is_apache, $is_nginx; // wp-includes/vars.php
108
+
109
+ if ( $is_apache ) {
110
+ return $this->doc_root . $this->wp_dirs[ $which ] . '.htaccess';
111
+ }
112
+
113
+ elseif ( $is_nginx ) {
114
+ return NULL; /* MUST FIX */
115
+ }
116
+
117
+ else {
118
+ return NULL; /* NOT SUPPORTED */
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Get contents in .htaccess in wp-content/(plugins|themes)/
124
+ *
125
+ * @param string 'plugins' or 'themes'
126
+ * @return array contents of configuration file
127
+ */
128
+ private function get_rewrite_rule( $which ) {
129
+ $file = $this->get_rewrite_file( $which );
130
+ $exist = @file_exists( $file );
131
+
132
+ // check permission
133
+ if ( $exist ) {
134
+ if ( ! @is_readable( $file ) )
135
+ return FALSE;
136
+ } else {
137
+ if ( ! @is_readable( dirname( $file ) ) )
138
+ return FALSE;
139
+ }
140
+
141
+ // http://php.net/manual/en/function.file.php#refsect1-function.file-returnvalues
142
+ @ini_set( 'auto_detect_line_endings', TRUE );
143
+
144
+ // get file contents as an array
145
+ return $exist ? @file( $file, FILE_IGNORE_NEW_LINES ) : array();
146
+ }
147
+
148
+ /**
149
+ * Put contents to .htaccess in wp-content/(plugins|themes)/
150
+ *
151
+ * @param string 'plugins' or 'themes'
152
+ * @param array contents of configuration file
153
+ */
154
+ private function put_rewrite_rule( $which, $content ) {
155
+ $file = $this->get_rewrite_file( $which );
156
+ if ( ! $file || FALSE === file_put_contents( $file, implode( PHP_EOL, $content ), LOCK_EX ) )
157
+ return FALSE;
158
+
159
+ // if content is empty then remove file
160
+ if ( empty( $content ) )
161
+ unlink( $file );
162
+
163
+ return TRUE;
164
+ }
165
+
166
+ /**
167
+ * Check if the block of rewrite rule exists
168
+ *
169
+ * @param string 'plugins' or 'themes'
170
+ * @return bool TRUE or FALSE
171
+ */
172
+ private function get_rewrite_stat( $which ) {
173
+ global $is_apache, $is_nginx; // wp-includes/vars.php
174
+
175
+ if ( $is_apache ) {
176
+ if ( FALSE === ( $content = $this->get_rewrite_rule( $which ) ) )
177
+ return FALSE;
178
+
179
+ $block = $this->find_rewrite_block( $content );
180
+ return empty( $block ) ? FALSE : TRUE;
181
+ }
182
+
183
+ elseif ( $is_nginx ) {
184
+ // https://www.wordfence.com/blog/2014/05/nginx-wordfence-falcon-engine-php-fpm-fastcgi-fast-cgi/
185
+ return -1; /* CURRENTLY NOT SUPPORTED */
186
+ }
187
+
188
+ else {
189
+ return -1; /* NOT SUPPORTED */
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Remove the block of rewrite rule
195
+ *
196
+ * @param array contents of configuration file
197
+ * @return array array of contents without rewrite rule
198
+ */
199
+ private function remove_rewrite_block( $content, $block ) {
200
+ $block = array_reverse( $block, TRUE );
201
+
202
+ if ( 2 <= count( $block ) ) {
203
+ reset( $block );
204
+ while (
205
+ ( list( $key_end, $val_end ) = each( $block ) ) &&
206
+ ( list( $key_begin, $val_begin ) = each( $block ) )
207
+ ) {
208
+ array_splice( $content, $key_begin, $key_end - $key_begin + 1 );
209
+ }
210
+ }
211
+
212
+ return $content;
213
+ }
214
+
215
+ /**
216
+ * Append the block of rewrite rule
217
+ *
218
+ * @param string 'plugins' or 'themes'
219
+ * @param array contents of configuration file
220
+ * @return array array of contents with the block of rewrite rule
221
+ */
222
+ private function append_rewrite_block( $which, $content ) {
223
+ $server_type = $this->get_server_type();
224
+
225
+ return $server_type ? array_merge(
226
+ $content,
227
+ str_replace(
228
+ array( '%REWRITE_BASE%', '%WP_CONTENT_DIR%' ),
229
+ array( $this->base_uri, WP_CONTENT_DIR ),
230
+ $this->rewrite_rule[ $server_type ][ $which ]
231
+ )
232
+ ) : array();
233
+ }
234
+
235
+ /**
236
+ * Add rewrite rule to server configration
237
+ *
238
+ * @param string 'plugins' or 'themes'
239
+ */
240
+ private function add_rewrite_rule( $which ) {
241
+ global $is_apache, $is_nginx; // wp-includes/vars.php
242
+
243
+ if ( $is_apache ) {
244
+ if ( FALSE === ( $content = $this->get_rewrite_rule( $which ) ) )
245
+ return FALSE;
246
+
247
+ $block = $this->find_rewrite_block( $content );
248
+
249
+ if ( empty( $block ) ) {
250
+ $content = $this->remove_rewrite_block( $content, $block );
251
+ $content = $this->append_rewrite_block( $which, $content );
252
+ return $this->put_rewrite_rule( $which, $content );
253
+ }
254
+ }
255
+
256
+ return TRUE;
257
+ }
258
+
259
+ /**
260
+ * Delete rewrite rule to server configration
261
+ *
262
+ * @param string 'plugins' or 'themes'
263
+ */
264
+ private function del_rewrite_rule( $which ) {
265
+ global $is_apache, $is_nginx; // wp-includes/vars.php
266
+
267
+ if ( $is_apache ) {
268
+ if ( FALSE === ( $content = $this->get_rewrite_rule( $which ) ) )
269
+ return FALSE;
270
+
271
+ $block = $this->find_rewrite_block( $content );
272
+
273
+ if ( ! empty( $block ) ) {
274
+ $content = $this->remove_rewrite_block( $content, $block );
275
+ return $this->put_rewrite_rule( $which, $content );
276
+ }
277
+ }
278
+
279
+ return TRUE;
280
+ }
281
+
282
+ /**
283
+ * Check rewrite rules
284
+ *
285
+ */
286
+ public static function check_rewrite_all() {
287
+ $status = array();
288
+ $rewrite = self::get_instance();
289
+
290
+ foreach ( array_keys( $rewrite->rewrite_rule['apache'] ) as $key ) {
291
+ $status[ $key ] = $rewrite->get_rewrite_stat( $key );
292
+ }
293
+
294
+ return $status;
295
+ }
296
+
297
+ /**
298
+ * Activate all rewrite rules according to the settings
299
+ *
300
+ */
301
+ public static function activate_rewrite_all( $options ) {
302
+ $rewrite = self::get_instance();
303
+
304
+ foreach ( array_keys( $rewrite->rewrite_rule['apache'] ) as $key ) {
305
+ if ( $options[ $key ] )
306
+ // if it fails to write, then return FALSE
307
+ $options[ $key ] = $rewrite->add_rewrite_rule( $key ) ? TRUE : FALSE;
308
+ else
309
+ // regardless of the result, return FALSE
310
+ $options[ $key ] = $rewrite->del_rewrite_rule( $key ) ? FALSE : FALSE;
311
+ }
312
+
313
+ return $options;
314
+ }
315
+
316
+ /**
317
+ * Deactivate all rewrite rules
318
+ *
319
+ */
320
+ public static function deactivate_rewrite_all() {
321
+ $rewrite = self::get_instance();
322
+
323
+ foreach ( array_keys( $rewrite->rewrite_rule['apache'] ) as $key ) {
324
+ if ( FALSE === $rewrite->del_rewrite_rule( $key ) )
325
+ return FALSE;
326
+ }
327
+
328
+ return TRUE;
329
+ }
330
+
331
+ /**
332
+ * Return list of target directories.
333
+ *
334
+ */
335
+ public static function get_dirs() {
336
+ $rewrite = self::get_instance();
337
+ return str_replace( $rewrite->doc_root, '', $rewrite->wp_dirs );
338
+ }
339
+
340
+ }
admin/includes/tab-accesslog.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class IP_Geo_Block_Admin_Tab {
3
+
4
+ public static function tab_setup( $context ) {
5
+ $option_slug = IP_Geo_Block::PLUGIN_NAME;
6
+ $option_name = IP_Geo_Block::OPTION_NAME;
7
+ $settings = IP_Geo_Block::get_option();
8
+
9
+ register_setting(
10
+ $option_slug,
11
+ $option_name
12
+ );
13
+
14
+ if ( $settings['validation']['reclogs'] ) :
15
+
16
+ /*----------------------------------------*
17
+ * Validation logs
18
+ *----------------------------------------*/
19
+ $section = IP_Geo_Block::PLUGIN_NAME . '-accesslog';
20
+ add_settings_section(
21
+ $section,
22
+ __( 'Validation logs', 'ip-geo-block' ),
23
+ array( __CLASS__, 'list_accesslog' ),
24
+ $option_slug
25
+ );
26
+
27
+ // footable filter
28
+ $field = 'filter_logs';
29
+ add_settings_field(
30
+ $option_name.'_'.$field,
31
+ __( 'Filter logs', 'ip-geo-block' ),
32
+ array( $context, 'callback_field' ),
33
+ $option_slug,
34
+ $section,
35
+ array(
36
+ 'type' => 'text',
37
+ 'option' => $option_name,
38
+ 'field' => $field,
39
+ 'value' => '',
40
+ 'after' => '<a class="button button-secondary" id="ip-geo-block-reset-filter" title="' . __( 'Reset', 'ip-geo-block' ) . '" href="javascript:void(0)">'. __( 'Reset', 'ip-geo-block' ) . '</a>',
41
+ )
42
+ );
43
+
44
+ $field = 'clear_logs';
45
+ add_settings_field(
46
+ $option_name.'_'.$field,
47
+ __( 'Clear logs', 'ip-geo-block' ),
48
+ array( $context, 'callback_field' ),
49
+ $option_slug,
50
+ $section,
51
+ array(
52
+ 'type' => 'button',
53
+ 'option' => $option_name,
54
+ 'field' => $field,
55
+ 'value' => __( 'Clear now', 'ip-geo-block' ),
56
+ 'after' => '<div id="ip-geo-block-logs"></div>',
57
+ )
58
+ );
59
+
60
+ $field = 'export_logs';
61
+ add_settings_field(
62
+ $option_name.'_'.$field,
63
+ __( 'Export logs', 'ip-geo-block' ),
64
+ array( $context, 'callback_field' ),
65
+ $option_slug,
66
+ $section,
67
+ array(
68
+ 'type' => 'none',
69
+ 'before' => '<a class="button button-secondary" id="ip-geo-block-export-logs" title="' . __( 'Export to the local file', 'ip-geo-block' ) . '" href="javascript:void(0)">'. __( 'Export csv', 'ip-geo-block' ) . '</a>',
70
+ 'after' => '<div id="ip-geo-block-export"></div>',
71
+ )
72
+ );
73
+
74
+ else:
75
+
76
+ /*----------------------------------------*
77
+ * Warning
78
+ *----------------------------------------*/
79
+ $section = IP_Geo_Block::PLUGIN_NAME . '-accesslog';
80
+ add_settings_section(
81
+ $section,
82
+ __( 'Validation logs', 'ip-geo-block' ),
83
+ array( __CLASS__, 'warn_accesslog' ),
84
+ $option_slug
85
+ );
86
+
87
+ $field = 'warning';
88
+ add_settings_field(
89
+ $option_name.'_'.$field,
90
+ '&hellip;',
91
+ array( $context, 'callback_field' ),
92
+ $option_slug,
93
+ $section,
94
+ array(
95
+ 'type' => 'none',
96
+ 'after' => '&hellip;',
97
+ )
98
+ );
99
+
100
+ endif;
101
+ }
102
+
103
+ /**
104
+ * Function that fills the section with the desired content.
105
+ *
106
+ */
107
+ public static function list_accesslog() {
108
+ // same as in tab-settings.php
109
+ $dfn = __( '<dfn title="Validation log of request to %s.">%s</dfn>', 'ip-geo-block' );
110
+ $target = array(
111
+ 'comment' => sprintf( $dfn, 'wp-comments-post.php', __( 'Comment post', 'ip-geo-block' ) ),
112
+ 'xmlrpc' => sprintf( $dfn, 'xmlrpc.php', __( 'XML-RPC', 'ip-geo-block' ) ),
113
+ 'login' => sprintf( $dfn, 'wp-login.php', __( 'Login form', 'ip-geo-block' ) ),
114
+ 'admin' => sprintf( $dfn, 'wp-admin/*.php', __( 'Admin area', 'ip-geo-block' ) ),
115
+ 'public' => sprintf( $dfn, __( 'public facing pages', 'ip-geo-block' ), __( 'Public facing pages', 'ip-geo-block' ) ),
116
+ );
117
+
118
+ foreach ( $target as $key => $val ) {
119
+ echo '<h4>', $val, '</h4>', "\n";
120
+ echo '<table class="fixed ', IP_Geo_Block::PLUGIN_NAME, '-log" data-page-size="10" data-limit-navigation="5" data-filter="#', IP_Geo_Block::OPTION_NAME, '_filter_logs" data-filter-text-only="true"><thead><tr>', "\n";
121
+ echo '<th data-type="numeric">', __( 'Date', 'ip-geo-block' ), '</th>', "\n";
122
+ echo '<th>', __( 'IP address', 'ip-geo-block' ), '</th>', "\n";
123
+ echo '<th>', __( 'Code', 'ip-geo-block' ), '</th>', "\n";
124
+ echo '<th>', __( 'Result', 'ip-geo-block' ), '</th>', "\n";
125
+ echo '<th data-hide="phone,tablet">', __( 'Request', 'ip-geo-block' ), '</th>', "\n";
126
+ echo '<th data-hide="all">', __( 'User agent', 'ip-geo-block' ), '</th>', "\n";
127
+ echo '<th data-hide="all">', __( 'HTTP headers', 'ip-geo-block' ), '</th>', "\n";
128
+ echo '<th data-hide="all">', __( '$_POST data', 'ip-geo-block' ), '</th>', "\n";
129
+ echo '</tr></thead><tbody id="', IP_Geo_Block::PLUGIN_NAME, '-log-', $key, '">', "\n";
130
+ echo <<<EOT
131
+ </tbody>
132
+ <tfoot class="hide-if-no-paging">
133
+ <tr>
134
+ <td colspan="5">
135
+ <div class="pagination pagination-centered"></div>
136
+ </td>
137
+ </tr>
138
+ </tfoot>
139
+ </table>
140
+
141
+ EOT;
142
+ }
143
+ }
144
+
145
+ public static function warn_accesslog() {
146
+ echo '<p>', __( 'Current selection of [<strong>Record validation logs</strong>] on [<strong>Settings</strong>] tab is [<strong>Disable</strong>].', 'ip-geo-block' ), '</p>', "\n";
147
+ echo '<p>', __( 'Please select the proper condition to record and analyze the validation logs.', 'ip-geo-block' ), '</p>', "\n";
148
+ }
149
+
150
+ }
admin/includes/tab-attribution.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class IP_Geo_Block_Admin_Tab {
3
+
4
+ public static function tab_setup( $context ) {
5
+ $option_slug = IP_Geo_Block::PLUGIN_NAME;
6
+ $option_name = IP_Geo_Block::OPTION_NAME;
7
+
8
+ register_setting(
9
+ $option_slug,
10
+ $option_name
11
+ );
12
+
13
+ $section = IP_Geo_Block::PLUGIN_NAME . '-attribution';
14
+ add_settings_section(
15
+ $section,
16
+ __( 'Attribution links', 'ip-geo-block' ),
17
+ NULL,
18
+ $option_slug
19
+ );
20
+
21
+ $field = 'attribution';
22
+ $providers = IP_Geo_Block_Provider::get_providers( 'link' );
23
+
24
+ foreach ( $providers as $provider => $key ) {
25
+ add_settings_field(
26
+ $option_name.'_'.$field.'_'.$provider,
27
+ $provider,
28
+ array( $context, 'callback_field' ),
29
+ $option_slug,
30
+ $section,
31
+ array(
32
+ 'type' => 'html',
33
+ 'option' => $option_name,
34
+ 'field' => $field,
35
+ 'value' => $key,
36
+ )
37
+ );
38
+ }
39
+ }
40
+
41
+ }
admin/includes/tab-geolocation.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class IP_Geo_Block_Admin_Tab {
3
+
4
+ public static function tab_setup( $context ) {
5
+ $option_slug = IP_Geo_Block::PLUGIN_NAME;
6
+ $option_name = IP_Geo_Block::OPTION_NAME;
7
+ $options = IP_Geo_Block::get_option();
8
+
9
+ register_setting(
10
+ $option_slug,
11
+ $option_name
12
+ );
13
+
14
+ /*----------------------------------------*
15
+ * Geolocation
16
+ *----------------------------------------*/
17
+ $section = IP_Geo_Block::PLUGIN_NAME . '-search';
18
+ add_settings_section(
19
+ $section,
20
+ __( 'Search IP address geolocation', 'ip-geo-block' ),
21
+ NULL,
22
+ $option_slug
23
+ );
24
+
25
+ // make providers list
26
+ $list = array();
27
+ $providers = IP_Geo_Block_Provider::get_providers( 'key' );
28
+
29
+ foreach ( $providers as $provider => $key ) {
30
+ if ( ! is_string( $key ) ||
31
+ ! empty( $options['providers'][ $provider ] ) ) {
32
+ $list += array( $provider => $provider );
33
+ }
34
+ }
35
+
36
+ $field = 'service';
37
+ $provider = array_keys( $providers );
38
+ add_settings_field(
39
+ $option_name.'_'.$field,
40
+ __( 'Geolocation service', 'ip-geo-block' ),
41
+ array( $context, 'callback_field' ),
42
+ $option_slug,
43
+ $section,
44
+ array(
45
+ 'type' => 'select',
46
+ 'option' => $option_name,
47
+ 'field' => $field,
48
+ 'value' => $provider[0],
49
+ 'list' => $list,
50
+ )
51
+ );
52
+
53
+ // preset IP address
54
+ if ( isset( $_GET['ip'] ) ) {
55
+ $list = str_replace( '***', '0', $_GET['ip'] ); // Anonymize IP address
56
+ $list = filter_var( $list, FILTER_VALIDATE_IP ) ? $list : '';
57
+ }
58
+ else {
59
+ $list = '';
60
+ }
61
+
62
+ $field = 'ip_address';
63
+ add_settings_field(
64
+ $option_name.'_'.$field,
65
+ __( 'IP address', 'ip-geo-block' ),
66
+ array( $context, 'callback_field' ),
67
+ $option_slug,
68
+ $section,
69
+ array(
70
+ 'type' => 'text',
71
+ 'option' => $option_name,
72
+ 'field' => $field,
73
+ 'value' => $list,
74
+ )
75
+ );
76
+
77
+ $field = 'get_location';
78
+ add_settings_field(
79
+ $option_name.'_'.$field,
80
+ __( 'Find geolocation', 'ip-geo-block' ),
81
+ array( $context, 'callback_field' ),
82
+ $option_slug,
83
+ $section,
84
+ array(
85
+ 'type' => 'button',
86
+ 'option' => $option_name,
87
+ 'field' => $field,
88
+ 'value' => __( 'Search now', 'ip-geo-block' ),
89
+ 'after' => '<div id="ip-geo-block-loading"></div>',
90
+ )
91
+ );
92
+ }
93
+
94
+ }
admin/includes/tab-settings.php ADDED
@@ -0,0 +1,1334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php';
3
+ require_once IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-rewrite.php';
4
+
5
+ if ( ! function_exists( 'get_plugins' ) )
6
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
7
+
8
+ class IP_Geo_Block_Admin_Tab {
9
+
10
+ public static function tab_setup( $context ) {
11
+ $plugin_slug = IP_Geo_Block::PLUGIN_NAME; // 'ip-geo-block'
12
+ $option_slug = IP_Geo_Block::PLUGIN_NAME; // 'ip-geo-block'
13
+ $option_name = IP_Geo_Block::OPTION_NAME; // 'ip_geo_block_settings'
14
+ $options = IP_Geo_Block::get_option();
15
+
16
+ // Get the country code
17
+ $key = IP_Geo_Block::get_geolocation();
18
+
19
+ /**
20
+ * Register a setting and its sanitization callback.
21
+ * @link http://codex.wordpress.org/Function_Reference/register_setting
22
+ *
23
+ * register_setting( $option_group, $option_name, $sanitize_callback );
24
+ * @param string $option_group A settings group name.
25
+ * @param string $option_name The name of an option to sanitize and save.
26
+ * @param string $sanitize_callback A callback function that sanitizes option values.
27
+ * @since 2.7.0
28
+ */
29
+ register_setting(
30
+ $option_slug,
31
+ $option_name,
32
+ array( $context, 'validate_settings' )
33
+ );
34
+
35
+ /**
36
+ * Add new section to a new page inside the existing page.
37
+ * @link http://codex.wordpress.org/Function_Reference/add_settings_section
38
+ *
39
+ * add_settings_section( $id, $title, $callback, $page );
40
+ * @param string $id String for use in the 'id' attribute of tags.
41
+ * @param string $title Title of the section.
42
+ * @param string $callback Function that fills the section with the desired content.
43
+ * @param string $page The menu page on which to display this section.
44
+ * @since 2.7.0
45
+ */
46
+ /*----------------------------------------*
47
+ * Validation rule settings
48
+ *----------------------------------------*/
49
+ $section = $plugin_slug . '-validation-rule';
50
+ add_settings_section(
51
+ $section,
52
+ __( 'Validation rule settings', 'ip-geo-block' ),
53
+ NULL,
54
+ $option_slug
55
+ );
56
+
57
+ /**
58
+ * Register a settings field to the settings page and section.
59
+ * @link http://codex.wordpress.org/Function_Reference/add_settings_field
60
+ *
61
+ * add_settings_field( $id, $title, $callback, $page, $section, $args );
62
+ * @param string $id String for use in the 'id' attribute of tags.
63
+ * @param string $title Title of the field.
64
+ * @param string $callback Function that fills the field with the desired inputs.
65
+ * @param string $page The menu page on which to display this field.
66
+ * @param string $section The section of the settings page in which to show the box.
67
+ * @param array $args Additional arguments that are passed to the $callback function.
68
+ */
69
+ $field = 'ip_country';
70
+ add_settings_field(
71
+ $option_name.'_'.$field,
72
+ __( '<dfn title="You can confirm the appropriate Geolocation APIs and country code by referring &#8220;Scan your country code&#8221;.">Your IP address / Country</dfn>', 'ip-geo-block' ),
73
+ array( $context, 'callback_field' ),
74
+ $option_slug,
75
+ $section,
76
+ array(
77
+ 'type' => 'html',
78
+ 'option' => $option_name,
79
+ 'field' => $field,
80
+ 'value' => esc_html( $key['ip'] . ' / ' . ( $key['code'] && isset( $key['provider'] ) ? $key['code'] . ' (' . $key['provider'] . ')' : __( 'UNKNOWN', 'ip-geo-block' ) ) ),
81
+ 'after' => '&nbsp;<a class="button button-secondary" id="ip-geo-block-scan-code" title="' . __( 'Scan all the APIs you selected at Geolocation API settings', 'ip-geo-block' ) . '" href="javascript:void(0)">' . __( 'Scan your country code', 'ip-geo-block' ) . '</a><div id="ip-geo-block-scanning"></div>',
82
+ )
83
+ );
84
+
85
+ // If the matching rule is not initialized, then add a caution
86
+ $rule = array(
87
+ -1 => NULL,
88
+ 0 => __( 'Whitelist', 'ip-geo-block' ),
89
+ 1 => __( 'Blacklist', 'ip-geo-block' ),
90
+ );
91
+
92
+ $rule_desc = array(
93
+ __( 'Please select either &#8220;Whitelist&#8221; or &#8220;Blacklist&#8221;.', 'ip-geo-block' ),
94
+ __( '<dfn title="&#8220;Block by country&#8221; will be bypassed in case of empty. All the countries will be blocked in case you put &#8220;XX&#8221; only.">Whitelist of country code</dfn>', 'ip-geo-block' ) . '<br />(<a rel="noreferrer" href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements" title="ISO 3166-1 alpha-2 - Wikipedia, the free encyclopedia">ISO 3166-1 alpha-2</a>)',
95
+ __( '<dfn title="&#8220;Block by country&#8221; will be bypassed in case of empty. Please consider to include &#8220;ZZ&#8221; which means UNKNOWN country.">Blacklist of country code</dfn>', 'ip-geo-block' ) . '<br />(<a rel="noreferrer" href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements" title="ISO 3166-1 alpha-2 - Wikipedia, the free encyclopedia">ISO 3166-1 alpha-2</a>)',
96
+ );
97
+
98
+ $comma = array(
99
+ '<span class="ip-geo-block-sup">' . __( '(comma separated)', 'ip-geo-block' ) . '</span>',
100
+ '<span class="ip-geo-block-sup">' . __( '(comma or RET separated)', 'ip-geo-block' ) . '</span>',
101
+ );
102
+
103
+ // Matching rule
104
+ $field = 'matching_rule';
105
+ add_settings_field(
106
+ $option_name.'_'.$field,
107
+ '<dfn title="' . $rule_desc[0] . '">' . __( 'Matching rule', 'ip-geo-block' ) . '</dfn>',
108
+ array( $context, 'callback_field' ),
109
+ $option_slug,
110
+ $section,
111
+ array(
112
+ 'type' => 'select',
113
+ 'option' => $option_name,
114
+ 'field' => $field,
115
+ 'value' => $options[ $field ],
116
+ 'list' => $rule,
117
+ 'desc' => array(
118
+ -1 => $rule_desc[0],
119
+ 0 => __( 'A request from which the country code or IP address is <strong>NOT</strong> in the whitelist will be blocked.', 'ip-geo-block' ),
120
+ 1 => __( 'A request from which the country code or IP address is in the blacklist will be blocked.', 'ip-geo-block' ),
121
+ ),
122
+ 'before' => '<input type="hidden" name="ip_geo_block_settings[version]" value="' . esc_html( $options['version'] ) . '" />',
123
+ 'after' => '<div class="ip-geo-block-desc"></div>',
124
+ )
125
+ );
126
+
127
+ // Country code for matching rule (ISO 3166-1 alpha-2)
128
+ $field = 'white_list';
129
+ add_settings_field(
130
+ $option_name.'_'.$field,
131
+ $rule_desc[1],
132
+ array( $context, 'callback_field' ),
133
+ $option_slug,
134
+ $section,
135
+ array(
136
+ 'type' => 'text',
137
+ 'option' => $option_name,
138
+ 'field' => $field,
139
+ 'value' => $options[ $field ],
140
+ 'after' => $comma[0],
141
+ )
142
+ );
143
+
144
+ $field = 'black_list';
145
+ add_settings_field(
146
+ $option_name.'_'.$field,
147
+ $rule_desc[2],
148
+ array( $context, 'callback_field' ),
149
+ $option_slug,
150
+ $section,
151
+ array(
152
+ 'type' => 'text',
153
+ 'option' => $option_name,
154
+ 'field' => $field,
155
+ 'value' => $options[ $field ],
156
+ 'after' => $comma[0],
157
+ )
158
+ );
159
+
160
+ // White list of extra IP addresses prior to country code (CIDR)
161
+ $field = 'extra_ips';
162
+ $key = 'white_list';
163
+ add_settings_field(
164
+ $option_name.'_'.$field.'_'.$key,
165
+ __( '<dfn title="e.g. &#8220;192.0.64.0/18&#8221; for Jetpack server, &#8220;69.46.36.0/27&#8221; for WordFence server">Whitelist of extra IP addresses prior to country code</dfn>', 'ip-geo-block' ) .
166
+ ' (<a rel="noreferrer" href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" title="Classless Inter-Domain Routing - Wikipedia, the free encyclopedia">CIDR</a>)',
167
+ array( $context, 'callback_field' ),
168
+ $option_slug,
169
+ $section,
170
+ array(
171
+ 'type' => 'textarea',
172
+ 'option' => $option_name,
173
+ 'field' => $field,
174
+ 'sub-field' => $key,
175
+ 'value' => $options[ $field ][ $key ],
176
+ 'after' => $comma[1],
177
+ )
178
+ );
179
+
180
+ // Black list of extra IP addresses prior to country code (CIDR)
181
+ $key = 'black_list';
182
+ add_settings_field(
183
+ $option_name.'_'.$field.'_'.$key,
184
+ __( '<dfn title="Server level access control is recommended (e.g. .htaccess).">Blacklist of extra IP addresses prior to country code</dfn>', 'ip-geo-block' ) .
185
+ ' (<a rel="noreferrer" href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" title="Classless Inter-Domain Routing - Wikipedia, the free encyclopedia">CIDR</a>)',
186
+ array( $context, 'callback_field' ),
187
+ $option_slug,
188
+ $section,
189
+ array(
190
+ 'type' => 'textarea',
191
+ 'option' => $option_name,
192
+ 'field' => $field,
193
+ 'sub-field' => $key,
194
+ 'value' => $options[ $field ][ $key ],
195
+ 'after' => $comma[1],
196
+ )
197
+ );
198
+
199
+ // $_SERVER keys to retrieve extra IP addresses
200
+ $field = 'validation';
201
+ $key = 'proxy';
202
+ add_settings_field(
203
+ $option_name.'_'.$field.'_'.$key,
204
+ __( '<dfn title="e.g. HTTP_X_FORWARDED_FOR">$_SERVER keys to retrieve extra IP addresses</dfn>', 'ip-geo-block' ),
205
+ array( $context, 'callback_field' ),
206
+ $option_slug,
207
+ $section,
208
+ array(
209
+ 'type' => 'text',
210
+ 'option' => $option_name,
211
+ 'field' => $field,
212
+ 'sub-field' => $key,
213
+ 'value' => $options[ $field ][ $key ],
214
+ 'after' => $comma[0],
215
+ )
216
+ );
217
+
218
+ // Bad signatures
219
+ $field = 'signature';
220
+ add_settings_field(
221
+ $option_name.'_'.$field,
222
+ __( '<dfn title="It validates malicious signatures independently of &#8220;Block by country&#8221; and &#8220;Prevent Zero-day Exploit&#8221; for the target &#8220;Admin area&#8221;, &#8220;Admin ajax/post&#8221;, &#8220;Plugins area&#8221; and &#8220;Themes area&#8221;.">Bad signatures in query</dfn> <nobr>(<a href="javascript:void(0)" id="ip-geo-block-decode" title="When you find ugly character string in the text area, please click to restore."><span id="ip-geo-block-cycle"></span></a>)</nobr>', 'ip-geo-block' ),
223
+ array( $context, 'callback_field' ),
224
+ $option_slug,
225
+ $section,
226
+ array(
227
+ 'type' => 'textarea',
228
+ 'option' => $option_name,
229
+ 'field' => $field,
230
+ 'value' => $options[ $field ],
231
+ 'after' => $comma[1],
232
+ )
233
+ );
234
+
235
+ // Response code (RFC 2616)
236
+ $field = 'response_code';
237
+ add_settings_field(
238
+ $option_name.'_'.$field,
239
+ sprintf( __( '<dfn title="You can put your original 403.php and so on into your theme directory.">Response code</dfn> %s', 'ip-geo-block' ), '(<a rel="noreferrer" href="http://tools.ietf.org/html/rfc2616#section-10" title="RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1">RFC 2616</a>)' ),
240
+ array( $context, 'callback_field' ),
241
+ $option_slug,
242
+ $section,
243
+ array(
244
+ 'type' => 'select',
245
+ 'option' => $option_name,
246
+ 'field' => $field,
247
+ 'value' => $options[ $field ],
248
+ 'list' => array(
249
+ 200 => '200 OK',
250
+ 301 => '301 Moved Permanently',
251
+ 302 => '302 Found',
252
+ 303 => '303 See Other',
253
+ 307 => '307 Temporary Redirect',
254
+ 400 => '400 Bad Request',
255
+ 403 => '403 Forbidden',
256
+ 404 => '404 Not Found',
257
+ 406 => '406 Not Acceptable',
258
+ 410 => '410 Gone',
259
+ 500 => '500 Internal Server Error',
260
+ 503 => '503 Service Unavailable',
261
+ ),
262
+ )
263
+ );
264
+
265
+ // Redirect URI
266
+ $field = 'redirect_uri';
267
+ add_settings_field(
268
+ $option_name.'_'.$field,
269
+ __( '<dfn title="Specify the URL for response code 2xx and 3xx. Front-end URL on your site would not be blocked to prevent loop of redirection even when you enable [Front-end target settings]. Empty URL is altered to your home.">Redirect URL</dfn>', 'ip-geo-block' ),
270
+ array( $context, 'callback_field' ),
271
+ $option_slug,
272
+ $section,
273
+ array(
274
+ 'class' => 'ip-geo-block-hide',
275
+ 'type' => 'text',
276
+ 'option' => $option_name,
277
+ 'field' => $field,
278
+ 'value' => $options[ $field ],
279
+ )
280
+ );
281
+
282
+ // Response message
283
+ $field = 'response_msg';
284
+ add_settings_field(
285
+ $option_name.'_'.$field,
286
+ __( '<dfn title="Specify the message for response code 4xx and 5xx.">Response message</dfn>', 'ip-geo-block' ),
287
+ array( $context, 'callback_field' ),
288
+ $option_slug,
289
+ $section,
290
+ array(
291
+ 'class' => 'ip-geo-block-hide',
292
+ 'type' => 'text',
293
+ 'option' => $option_name,
294
+ 'field' => $field,
295
+ 'value' => $options[ $field ],
296
+ )
297
+ );
298
+
299
+ // Max number of failed login attempts per IP address
300
+ $field = 'login_fails';
301
+ add_settings_field(
302
+ $option_name.'_'.$field,
303
+ __( '<dfn title="Applied to &#8220;XML-RPC&#8221; and &#8220;Login form&#8221;. Lockout period is defined as expiration time at &#8220;Cache settings&#8221;.">Max number of failed login attempts per IP address</dfn>', 'ip-geo-block' ),
304
+ array( $context, 'callback_field' ),
305
+ $option_slug,
306
+ $section,
307
+ array(
308
+ 'type' => 'select',
309
+ 'option' => $option_name,
310
+ 'field' => $field,
311
+ 'value' => $options[ $field ],
312
+ 'list' => array(
313
+ 0 => 0,
314
+ 1 => 1,
315
+ 3 => 3,
316
+ 5 => 5,
317
+ 7 => 7,
318
+ 10 => 10,
319
+ ),
320
+ )
321
+ );
322
+
323
+ // Validation timing
324
+ $field = 'validation';
325
+ $key = 'timing';
326
+ $options[ $field ][ $key ] = IP_Geo_Block_Opts::get_validation_timing();
327
+
328
+ add_settings_field(
329
+ $option_name.'_'.$field.'_'.$key,
330
+ '<dfn title="' . __( 'Select when to run the validation.', 'ip-geo-block' ) . '">' . __( 'Validation timing', 'ip-geo-block' ) . '</dfn>',
331
+ array( $context, 'callback_field' ),
332
+ $option_slug,
333
+ $section,
334
+ array(
335
+ 'type' => 'select',
336
+ 'option' => $option_name,
337
+ 'field' => $field,
338
+ 'sub-field' => $key,
339
+ 'value' => $options[ $field ][ $key ],
340
+ 'list' => array(
341
+ 0 => __( '&#8220;init&#8221; action hook', 'ip-geo-block' ),
342
+ 1 => __( '&#8220;mu-plugins&#8221; (ip-geo-block-mu.php)', 'ip-geo-block' ),
343
+ ),
344
+ 'desc' => array(
345
+ 0 => __( 'Validate at &#8220;init&#8221; action hook in the same manner as typical plugins.', 'ip-geo-block' ),
346
+ 1 => __( 'Validate at an earlier phase than other typical plugins. It can reduce load on server but has <a rel=\'noreferrer\' href=\'http://www.ipgeoblock.com/codex/validation-timing.html\' title=\'Validation timing | IP Geo Block\'>some restrictions</a>.', 'ip-geo-block' ),
347
+ ),
348
+ 'after' => '<div class="ip-geo-block-desc"></div>',
349
+ )
350
+ );
351
+
352
+ /*----------------------------------------*
353
+ * Back-end target settings
354
+ *----------------------------------------*/
355
+ $section = $plugin_slug . '-validation-target';
356
+ add_settings_section(
357
+ $section,
358
+ __( 'Back-end target settings', 'ip-geo-block' ),
359
+ array( __CLASS__, 'note_target' ),
360
+ $option_slug
361
+ );
362
+
363
+ // same as in tab-accesslog.php
364
+ $dfn = __( '<dfn title="Validate request to %s.">%s</dfn>', 'ip-geo-block' );
365
+ $target = array(
366
+ 'comment' => sprintf( $dfn, 'wp-comments-post.php', __( 'Comment post', 'ip-geo-block' ) ),
367
+ 'xmlrpc' => sprintf( $dfn, 'xmlrpc.php', __( 'XML-RPC', 'ip-geo-block' ) ),
368
+ 'login' => sprintf( $dfn, 'wp-login.php', __( 'Login form', 'ip-geo-block' ) ),
369
+ 'admin' => sprintf( $dfn, 'wp-admin/*.php', __( 'Admin area', 'ip-geo-block' ) ),
370
+ 'others' => sprintf( $dfn, 'executable files', __( 'Other areas', 'ip-geo-block' ) ),
371
+ 'public' => sprintf( $dfn, __( 'public facing pages', 'ip-geo-block' ), __( 'Public facing pages', 'ip-geo-block' ) ),
372
+ );
373
+
374
+ // Comment post
375
+ $field = 'validation';
376
+ $key = 'comment';
377
+ add_settings_field(
378
+ $option_name.'_'.$field.'_'.$key,
379
+ $target[ $key ],
380
+ array( $context, 'callback_field' ),
381
+ $option_slug,
382
+ $section,
383
+ array(
384
+ 'type' => 'checkbox',
385
+ 'option' => $option_name,
386
+ 'field' => $field,
387
+ 'sub-field' => $key,
388
+ 'value' => $options[ $field ][ $key ],
389
+ 'text' => __( 'Block by country', 'ip-geo-block' ),
390
+ )
391
+ );
392
+
393
+ // XML-RPC
394
+ $key = 'xmlrpc';
395
+ add_settings_field(
396
+ $option_name.'_'.$field.'_'.$key,
397
+ $target[ $key ],
398
+ array( $context, 'callback_field' ),
399
+ $option_slug,
400
+ $section,
401
+ array(
402
+ 'type' => 'select',
403
+ 'option' => $option_name,
404
+ 'field' => $field,
405
+ 'sub-field' => $key,
406
+ 'value' => $options[ $field ][ $key ],
407
+ 'list' => array(
408
+ 0 => __( 'Disable', 'ip-geo-block' ),
409
+ 1 => __( 'Block by country', 'ip-geo-block' ),
410
+ 2 => __( 'Completely close', 'ip-geo-block' ),
411
+ ),
412
+ )
413
+ );
414
+
415
+ $desc = array(
416
+ 'login' => __( 'Log in' ),
417
+ 'register' => __( 'Register' ),
418
+ 'resetpasss' => __( 'Password Reset' ),
419
+ 'lostpassword' => __( 'Lost Password' ),
420
+ 'postpass' => __( 'Password protected' ),
421
+ );
422
+
423
+ $list = '';
424
+ foreach ( $desc as $key => $val ) {
425
+ $list .= '<li><input type="checkbox" id="ip_geo_block_settings_login_action_' . $key . '" name="ip_geo_block_settings[login_action][' . $key . ']" value="1"' . checked( ! empty( $options['login_action'][ $key ] ), TRUE, FALSE ) . ' /><label for="ip_geo_block_settings_login_action_' . $key . '">' . $val . "</label></li>\n";
426
+ }
427
+
428
+ // Login form
429
+ $key = 'login';
430
+ add_settings_field(
431
+ $option_name.'_'.$field.'_'.$key,
432
+ $target[ $key ],
433
+ array( $context, 'callback_field' ),
434
+ $option_slug,
435
+ $section,
436
+ array(
437
+ 'type' => 'checkbox',
438
+ 'option' => $option_name,
439
+ 'field' => $field,
440
+ 'sub-field' => $key,
441
+ 'value' => $options[ $field ][ $key ],
442
+ 'text' => __( 'Block by country', 'ip-geo-block' ),
443
+ 'after' => '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">' . __( '<dfn title="Specify the individual action as a blocking target.">Target actions</dfn>', 'ip-geo-block' ) . "<li style='display:none'><ul>\n". $list . "</ul></li></ul>\n",
444
+ )
445
+ );
446
+
447
+ $list = array(
448
+ 1 => __( 'Block by country', 'ip-geo-block' ),
449
+ 2 => __( 'Prevent Zero-day Exploit', 'ip-geo-block' ),
450
+ );
451
+
452
+ $desc = array(
453
+ 1 => __( 'It will block a request related to the services for both public facing pages and the dashboard.', 'ip-geo-block' ),
454
+ 2 => __( 'Regardless of the country code, it will block a malicious request related to the services only for the dashboard.', 'ip-geo-block' ),
455
+ );
456
+
457
+ // Admin area
458
+ $key = 'admin';
459
+ add_settings_field(
460
+ $option_name.'_'.$field.'_'.$key,
461
+ $target[ $key ],
462
+ array( $context, 'callback_field' ),
463
+ $option_slug,
464
+ $section,
465
+ array(
466
+ 'type' => 'checkboxes',
467
+ 'option' => $option_name,
468
+ 'field' => $field,
469
+ 'sub-field' => $key,
470
+ 'value' => $options[ $field ][ $key ],
471
+ 'list' => $list,
472
+ 'desc' => $desc,
473
+ )
474
+ );
475
+
476
+ // Admin ajax/post
477
+ $key = 'ajax';
478
+ $val = esc_html( substr( IP_Geo_Block::$wp_path['admin'], 1 ) );
479
+ add_settings_field(
480
+ $option_name.'_'.$field.'_'.$key,
481
+ sprintf( $dfn, $val.'admin-(ajax|post).php', __( 'Admin ajax/post', 'ip-geo-block' ) ),
482
+ array( $context, 'callback_field' ),
483
+ $option_slug,
484
+ $section,
485
+ array(
486
+ 'type' => 'checkboxes',
487
+ 'option' => $option_name,
488
+ 'field' => $field,
489
+ 'sub-field' => $key,
490
+ 'value' => $options[ $field ][ $key ],
491
+ 'list' => $list,
492
+ 'desc' => $desc,
493
+ )
494
+ );
495
+
496
+ if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ):
497
+ // Excluded request for specific action or page to bypass WP-ZEP
498
+ $key = 'admin';
499
+ add_settings_field(
500
+ $option_name.'_exception_'.$key,
501
+ __( '<dfn title="Same effect as &#8220;ip-geo-block-bypass-admins&#8221; filter hook.">Exception for admin action and page</dfn>', 'ip-geo-block' ),
502
+ array( $context, 'callback_field' ),
503
+ $option_slug,
504
+ $section,
505
+ array(
506
+ 'type' => 'text',
507
+ 'option' => $option_name,
508
+ 'field' => 'exception',
509
+ 'sub-field' => $key,
510
+ 'value' => implode( ',', $options['exception'][ $key ] ),
511
+ 'after' => $comma[0],
512
+ )
513
+ );
514
+ endif;
515
+
516
+ array_unshift( $list, __( 'Disable', 'ip-geo-block' ) );
517
+ $desc = array(
518
+ __( 'Regardless of the country code, it will block a malicious request to <code>%s&hellip;/*.php</code>.', 'ip-geo-block' ),
519
+ __( 'It configures &#8220;%s&#8221; to validate a request to the PHP file which does not load WordPress core.', 'ip-geo-block' ),
520
+ __( '<dfn title="Select the item which causes undesired blocking in order to exclude from the validation target. Grayed item indicates &#8220;INACTIVE&#8221;.">Exceptions</dfn>', 'ip-geo-block' ),
521
+ );
522
+
523
+ // Set rewrite condition
524
+ $options['rewrite'] = IP_Geo_Block_Admin_Rewrite::check_rewrite_all();
525
+
526
+ // Get all the plugins
527
+ $exception = '';
528
+ $installed = get_plugins(); // @since 1.5.0
529
+ unset( $installed[ IP_GEO_BLOCK_BASE ] ); // exclude myself
530
+
531
+ $activated = get_site_option( 'active_sitewide_plugins' ); // @since 2.8.0
532
+ ! is_array( $activated ) and $activated = array();
533
+ $activated = array_merge( $activated, array_fill_keys( get_option( 'active_plugins' ), TRUE ) );
534
+
535
+ // Make a list of installed plugins
536
+ foreach ( $installed as $key => $val ) {
537
+ $active = isset( $activated[ $key ] );
538
+ $key = explode( '/', $key, 2 );
539
+ $key = esc_attr( $key[0] );
540
+ $exception .= '<li><input type="checkbox" id="ip_geo_block_settings_exception_plugins_' . $key
541
+ . '" name="ip_geo_block_settings[exception][plugins][' . $key
542
+ . ']" value="1"' . checked( in_array( $key, $options['exception']['plugins'] ), TRUE, FALSE )
543
+ . ' /><label for="ip_geo_block_settings_exception_plugins_' . $key
544
+ . ($active ? '">' : '" class="folding-inactive">') . esc_html( $val['Name'] ) . "</label></li>\n";
545
+ }
546
+
547
+ // Plugins area
548
+ $key = 'plugins';
549
+ $val = esc_html( IP_Geo_Block::$wp_path[ $key ] );
550
+ $tmp = '<input type="checkbox" id="ip_geo_block_settings_rewrite_' . $key
551
+ . '" name="ip_geo_block_settings[rewrite][' . $key . ']" '
552
+ . ' value="1"' . checked( $options['rewrite'][ $key ], TRUE, FALSE )
553
+ . disabled( $options['rewrite'][ $key ], -1, FALSE ) . ' />'
554
+ . '<label for="ip_geo_block_settings_rewrite_' . $key . '"><dfn title="'
555
+ . sprintf( $desc[1], $val . '.htaccess' )
556
+ . '">' . __( 'Force to load WP core', 'ip-geo-block' )
557
+ . '</dfn></label><br />';
558
+
559
+ add_settings_field(
560
+ $option_name.'_'.$field.'_'.$key,
561
+ sprintf( $dfn, $val.'&hellip;/*.php', __( 'Plugins area', 'ip-geo-block' ) ),
562
+ array( $context, 'callback_field' ),
563
+ $option_slug,
564
+ $section,
565
+ array(
566
+ 'type' => 'select',
567
+ 'option' => $option_name,
568
+ 'field' => $field,
569
+ 'sub-field' => $key,
570
+ 'value' => $options[ $field ][ $key ],
571
+ 'list' => $list,
572
+ 'desc' => array(
573
+ 2 => sprintf( $desc[0], $val ),
574
+ ),
575
+ 'before' => $tmp,
576
+ 'after' => '<div class="ip-geo-block-desc"></div>' . "\n"
577
+ . '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">' . $desc[2] . "<li style='display:none'><ul>\n"
578
+ . $exception
579
+ . "</ul></li></ul>\n",
580
+ )
581
+ );
582
+
583
+ // Get all the themes
584
+ $exception = '';
585
+ $installed = wp_get_themes( NULL ); // @since 3.4.0
586
+ $activated = wp_get_theme(); // @since 3.4.0
587
+ $activated = $activated->get( 'Name' );
588
+
589
+ // List of installed themes
590
+ foreach ( $installed as $key => $val ) {
591
+ $key = esc_attr( $key );
592
+ $active = ( ( $val = $val->get( 'Name' ) ) === $activated );
593
+ $exception .= '<li><input type="checkbox" id="ip_geo_block_settings_exception_themes_' . $key
594
+ . '" name="ip_geo_block_settings[exception][themes][' . $key
595
+ . ']" value="1"' . checked( in_array( $key, $options['exception']['themes'] ), TRUE, FALSE )
596
+ . ' /><label for="ip_geo_block_settings_exception_themes_' . $key
597
+ . ($active ? '">' : '" class="folding-inactive">') . esc_html( $val ) . "</label></li>\n";
598
+ }
599
+
600
+ // Themes area
601
+ $key = 'themes';
602
+ $val = esc_html( IP_Geo_Block::$wp_path[ $key ] );
603
+ $tmp = '<input type="checkbox" id="ip_geo_block_settings_rewrite_' . $key
604
+ . '" name="ip_geo_block_settings[rewrite][' . $key . ']" '
605
+ . ' value="1"' . checked( $options['rewrite'][ $key ], TRUE, FALSE )
606
+ . disabled( $options['rewrite'][ $key ], -1, FALSE ) . ' />'
607
+ . '<label for="ip_geo_block_settings_rewrite_' . $key . '"><dfn title="'
608
+ . sprintf( $desc[1], $val . '.htaccess' )
609
+ . '">' . __( 'Force to load WP core', 'ip-geo-block' )
610
+ . '</dfn></label><br />';
611
+
612
+ add_settings_field(
613
+ $option_name.'_'.$field.'_'.$key,
614
+ sprintf( $dfn, $val.'&hellip;/*.php', __( 'Themes area', 'ip-geo-block' ) ),
615
+ array( $context, 'callback_field' ),
616
+ $option_slug,
617
+ $section,
618
+ array(
619
+ 'type' => 'select',
620
+ 'option' => $option_name,
621
+ 'field' => $field,
622
+ 'sub-field' => $key,
623
+ 'value' => $options[ $field ][ $key ],
624
+ 'list' => $list,
625
+ 'desc' => array(
626
+ 2 => sprintf( $desc[0], $val ),
627
+ ),
628
+ 'before' => $tmp,
629
+ 'after' => '<div class="ip-geo-block-desc"></div>' . "\n"
630
+ . '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">' . $desc[2] . "<li style='display:none'><ul>\n"
631
+ . $exception
632
+ . "</ul></li></ul>\n",
633
+ )
634
+ );
635
+
636
+ /*----------------------------------------*
637
+ * Front-end settings
638
+ *----------------------------------------*/
639
+ $section = $plugin_slug . '-public';
640
+ add_settings_section(
641
+ $section,
642
+ __( 'Front-end target settings', 'ip-geo-block' ),
643
+ array( __CLASS__, 'note_public' ),
644
+ $option_slug
645
+ );
646
+
647
+ // Public facing pages
648
+ $key = 'public';
649
+ add_settings_field(
650
+ $option_name.'_'.$field.'_'.$key,
651
+ $target[ $key ],
652
+ array( $context, 'callback_field' ),
653
+ $option_slug,
654
+ $section,
655
+ array(
656
+ 'type' => 'checkbox',
657
+ 'option' => $option_name,
658
+ 'field' => $field,
659
+ 'sub-field' => $key,
660
+ 'value' => $options[ $field ][ $key ],
661
+ 'text' => __( 'Block by country', 'ip-geo-block' ),
662
+ )
663
+ );
664
+
665
+ // Default for matching rule on front-end
666
+ $rule[-1] = __( 'Follow &#8220;Validation rule settings&#8221;', 'ip-geo-block' );
667
+
668
+ // Matching rule
669
+ $field = 'public';
670
+ $key = 'matching_rule';
671
+ add_settings_field(
672
+ $option_name.'_'.$field.'_'.$key,
673
+ '<dfn title="' . $rule_desc[0] . '">' . __( 'Matching rule', 'ip-geo-block' ) . '</dfn>',
674
+ array( $context, 'callback_field' ),
675
+ $option_slug,
676
+ $section,
677
+ array(
678
+ 'type' => 'select',
679
+ 'option' => $option_name,
680
+ 'field' => $field,
681
+ 'sub-field' => $key,
682
+ 'value' => $options[ $field ][ $key ],
683
+ 'list' => $rule,
684
+ )
685
+ );
686
+
687
+ // Country code for matching rule (ISO 3166-1 alpha-2)
688
+ $key = 'white_list';
689
+ add_settings_field(
690
+ $option_name.'_'.$field.'_'.$key,
691
+ $rule_desc[1],
692
+ array( $context, 'callback_field' ),
693
+ $option_slug,
694
+ $section,
695
+ array(
696
+ 'type' => 'text',
697
+ 'option' => $option_name,
698
+ 'field' => $field,
699
+ 'sub-field' => $key,
700
+ 'value' => $options[ $field ][ $key ],
701
+ 'after' => $comma[0],
702
+ )
703
+ );
704
+
705
+ $key = 'black_list';
706
+ add_settings_field(
707
+ $option_name.'_'.$field.'_'.$key,
708
+ $rule_desc[2],
709
+ array( $context, 'callback_field' ),
710
+ $option_slug,
711
+ $section,
712
+ array(
713
+ 'type' => 'text',
714
+ 'option' => $option_name,
715
+ 'field' => $field,
716
+ 'sub-field' => $key,
717
+ 'value' => $options[ $field ][ $key ],
718
+ 'after' => $comma[0],
719
+ )
720
+ );
721
+
722
+ // List of page
723
+ $exception = '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">' . __( '<dfn title="Specify the individual page as a blocking target.">Page</dfn>', 'ip-geo-block' ) . "<li style='display:none'><ul>\n";
724
+ $tmp = get_pages();
725
+ if ( ! empty( $tmp ) ) {
726
+ foreach ( $tmp as $key ) {
727
+ $val = esc_attr( $key->post_name );
728
+ $exception .= '<li><input type="checkbox" id="ip_geo_block_settings_public_target_pages_' . $val . '" name="ip_geo_block_settings[public][target_pages][' . $val . ']" value="1"' . checked( isset( $options[ $field ]['target_pages'][ $val ] ), TRUE, FALSE ) . ' />';
729
+ $exception .= '<label for="ip_geo_block_settings_public_target_pages_' . $val . '">' . esc_html( $key->post_title ) . '</label></li>' . "\n";
730
+ }
731
+ }
732
+ $exception .= '</ul></li></ul>' . "\n";
733
+
734
+ // List of post type
735
+ $exception .= '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">' . __( '<dfn title="Specify the individual post type on a single page as a blocking target.">Post type</dfn>', 'ip-geo-block' ) . "<li style='display:none'><ul>\n";
736
+ $tmp = get_post_types( array( 'public' => TRUE ) );
737
+ if ( ! empty( $tmp ) ) {
738
+ foreach ( $tmp as $key ) {
739
+ $val = esc_attr( $key );
740
+ $exception .= '<li><input type="checkbox" id="ip_geo_block_settings_public_target_posts_' . $val . '" name="ip_geo_block_settings[public][target_posts][' . $val . ']" value="1"' . checked( isset( $options[ $field ]['target_posts'][ $val ] ), TRUE, FALSE ) . ' />';
741
+ $exception .= '<label for="ip_geo_block_settings_public_target_posts_' . $val . '">' . esc_html( $key ) . '</label></li>' . "\n";
742
+ }
743
+ }
744
+ $exception .= '</ul></li></ul>' . "\n";
745
+
746
+ // List of category
747
+ $exception .= '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">' . __( '<dfn title="Specify the individual category on a single page or archive page as a blocking target.">Category</dfn>', 'ip-geo-block' ) . "<li style='display:none'><ul>\n";
748
+ $tmp = get_categories( array( 'hide_empty' => FALSE ) );
749
+ if ( ! empty( $tmp ) ) {
750
+ foreach ( $tmp as $key ) {
751
+ $val = esc_attr( $key->slug );
752
+ $exception .= '<li><input type="checkbox" id="ip_geo_block_settings_public_target_cates_' . $val . '" name="ip_geo_block_settings[public][target_cates][' . $val . ']" value="1"' . checked( isset( $options[ $field ]['target_cates'][ $val ] ), TRUE, FALSE ) . ' />';
753
+ $exception .= '<label for="ip_geo_block_settings_public_target_cates_' . $val . '">' . esc_html( $key->name ) . '</label></li>' . "\n";
754
+ }
755
+ }
756
+ $exception .= '</ul></li></ul>' . "\n";
757
+
758
+ // List of tag
759
+ $exception .= '<ul class="ip_geo_block_settings_folding ip-geo-block-dropup">' . __( '<dfn title="Specify the individual tag on a single page or archive page as a blocking target.">Tag</dfn>', 'ip-geo-block' ) . "<li style='display:none'><ul>\n";
760
+ $tmp = get_tags( array( 'hide_empty' => FALSE ) );
761
+ if ( ! empty( $tmp ) ) {
762
+ foreach ( $tmp as $key ) {
763
+ $val = esc_attr( $key->slug );
764
+ $exception .= '<li><input type="checkbox" id="ip_geo_block_settings_public_target_tags_' . $val . '" name="ip_geo_block_settings[public][target_tags][' . $val . ']" value="1"' . checked( isset( $options[ $field ]['target_tags'][ $val ] ), TRUE, FALSE ) . ' />';
765
+ $exception .= '<label for="ip_geo_block_settings_public_target_tags_' . $val . '">' . esc_html( $key->name ) . '</label></li>' . "\n";
766
+ }
767
+ }
768
+ $exception .= '</ul></li></ul>' . "\n";
769
+
770
+ // Validation target
771
+ $key = 'target_rule';
772
+ add_settings_field(
773
+ $option_name.'_'.$field.'_'.$key,
774
+ '<dfn title="' . __( 'Specify the validation target on front-end.', 'ip-geo-block' ) . '">' . __( 'Validation target', 'ip-geo-block' ) . '</dfn>',
775
+ array( $context, 'callback_field' ),
776
+ $option_slug,
777
+ $section,
778
+ array(
779
+ 'type' => 'select',
780
+ 'option' => $option_name,
781
+ 'field' => $field,
782
+ 'sub-field' => $key,
783
+ 'value' => $options[ $field ][ $key ],
784
+ 'list' => array(
785
+ 0 => __( 'All requests', 'ip-geo-block' ),
786
+ 1 => __( 'Specify the targets', 'ip-geo-block' ),
787
+ ),
788
+ 'desc' => array(
789
+ 1 => __( "Notice that &#8220;Validation timing&#8221; is deferred till &#8220;wp&#8221; action hook. It means that this feature would not be compatible with any page caching.", 'ip-geo-block' ),
790
+ ),
791
+ 'after' => '<div class="ip-geo-block-desc"></div>' . "\n" . $exception,
792
+ )
793
+ );
794
+
795
+ // UA string and qualification
796
+ $key = 'ua_list';
797
+ add_settings_field(
798
+ $option_name.'_'.$field.'_'.$key,
799
+ '<dfn title="' . __( 'A part of user agent string and a qualification connected with a separator that indicates an applicable rule and can be &#8220;:&#8221; (pass) or &#8220;#&#8221; (block). A &#8220;qualification&#8221; can be &#8220;DNS&#8221;, &#8220;FEED&#8221;, country code or IP address with CIDR. A negative operator &#8220;!&#8221; can be placed just before a &#8220;qualification&#8221;.', 'ip-geo-block' ) . '">' . __( 'UA string and qualification', 'ip-geo-block' ) . '</dfn>',
800
+ array( $context, 'callback_field' ),
801
+ $option_slug,
802
+ $section,
803
+ array(
804
+ 'type' => 'textarea',
805
+ 'option' => $option_name,
806
+ 'field' => $field,
807
+ 'sub-field' => $key,
808
+ 'value' => $options[ $field ][ $key ],
809
+ 'after' => $comma[1],
810
+ )
811
+ );
812
+
813
+ if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ):
814
+ // Excluded action
815
+ $key = 'exception';
816
+ add_settings_field(
817
+ $option_name.'_'.$key.'_'.$field,
818
+ '<dfn title="' . __( 'Specify the name of action that is invariably blocked.', 'ip-geo-block' ) . '">' . __( 'Excluded actions', 'ip-geo-block' ) . '</dfn>',
819
+ array( $context, 'callback_field' ),
820
+ $option_slug,
821
+ $section,
822
+ array(
823
+ 'type' => 'text',
824
+ 'option' => $option_name,
825
+ 'field' => $key,
826
+ 'sub-field' => $field,
827
+ 'value' => implode( ',', $options[ $key ][ $field ] ),
828
+ 'after' => $comma[0],
829
+ )
830
+ );
831
+ endif;
832
+
833
+ // Simulation mode
834
+ $key = 'simulate';
835
+ add_settings_field(
836
+ $option_name.'_'.$field.'_'.$key,
837
+ '<dfn title="' . __( 'It enables to simulate validation without deployment. The results can be found at &#8220;Public facing pages&#8221; in Logs.', 'ip-geo-block' ) . '">' . __( 'Simulation mode', 'ip-geo-block' ) . '</dfn>',
838
+ array( $context, 'callback_field' ),
839
+ $option_slug,
840
+ $section,
841
+ array(
842
+ 'type' => 'checkbox',
843
+ 'option' => $option_name,
844
+ 'field' => $field,
845
+ 'sub-field' => $key,
846
+ 'value' => $options[ $field ][ $key ],
847
+ )
848
+ );
849
+
850
+ /*----------------------------------------*
851
+ * Geolocation service settings
852
+ *----------------------------------------*/
853
+ $section = $plugin_slug . '-provider';
854
+ add_settings_section(
855
+ $section,
856
+ __( 'Geolocation API settings', 'ip-geo-block' ),
857
+ array( __CLASS__, 'note_services' ),
858
+ $option_slug
859
+ );
860
+
861
+ // API selection and key settings
862
+ $field = 'providers';
863
+ add_settings_field(
864
+ $option_name.'_'.$field,
865
+ __( '<dfn title="Cache and local database are scanned at the top priority.">API selection and key settings</dfn>', 'ip-geo-block' ),
866
+ array( $context, 'callback_field' ),
867
+ $option_slug,
868
+ $section,
869
+ array(
870
+ 'type' => 'check-provider',
871
+ 'option' => $option_name,
872
+ 'field' => $field,
873
+ 'value' => $options[ $field ],
874
+ 'providers' => IP_Geo_Block_Provider::get_providers( 'key' ),
875
+ 'titles' => IP_Geo_Block_Provider::get_providers( 'type' ),
876
+ )
877
+ );
878
+
879
+ /*----------------------------------------*
880
+ * Local database settings
881
+ *----------------------------------------*/
882
+ // higher priority order
883
+ $providers = IP_Geo_Block_Provider::get_addons();
884
+ if ( empty( $providers ) ) {
885
+ $context->add_admin_notice( 'error',
886
+ sprintf(
887
+ __( 'Please download <a rel="noreferrer" href="https://github.com/tokkonopapa/WordPress-IP-Geo-API/archive/master.zip" title="Download the contents of tokkonopapa/WordPress-IP-Geo-API as a zip file">ZIP file</a> from <a rel="noreferrer" href="https://github.com/tokkonopapa/WordPress-IP-Geo-API" title="tokkonopapa/WordPress-IP-Geo-API - GitHub">WordPress-IP-Geo-API</a> and upload <code>ip-geo-api</code> to <code>%s</code> with write permission.', 'ip-geo-block' ),
888
+ apply_filters( 'ip-geo-block-api-dir', basename( WP_CONTENT_DIR ) )
889
+ )
890
+ );
891
+ }
892
+
893
+ $section = $plugin_slug . '-database';
894
+ add_settings_section(
895
+ $section,
896
+ __( 'Local database settings', 'ip-geo-block' ),
897
+ NULL,
898
+ $option_slug
899
+ );
900
+
901
+ // Local DBs for each API
902
+ foreach ( $providers as $provider ) {
903
+ if ( $geo = IP_Geo_Block_API::get_instance( $provider, NULL ) ) {
904
+ $geo->add_settings_field(
905
+ $provider,
906
+ $section,
907
+ $option_slug,
908
+ $option_name,
909
+ $options,
910
+ array( $context, 'callback_field' ),
911
+ __( 'database', 'ip-geo-block' ),
912
+ __( 'Last update: %s', 'ip-geo-block' )
913
+ );
914
+ }
915
+ }
916
+
917
+ // Auto updating (once a month)
918
+ $field = 'update';
919
+ add_settings_field(
920
+ $option_name.'_'.$field.'_auto',
921
+ __( 'Auto updating (once a month)', 'ip-geo-block' ),
922
+ array( $context, 'callback_field' ),
923
+ $option_slug,
924
+ $section,
925
+ array(
926
+ 'type' => 'checkbox',
927
+ 'option' => $option_name,
928
+ 'field' => $field,
929
+ 'sub-field' => 'auto',
930
+ 'value' => $options[ $field ]['auto'],
931
+ 'disabled' => empty( $providers ),
932
+ )
933
+ );
934
+
935
+ // Download database
936
+ add_settings_field(
937
+ $option_name.'_'.$field.'_download',
938
+ __( 'Download database', 'ip-geo-block' ),
939
+ array( $context, 'callback_field' ),
940
+ $option_slug,
941
+ $section,
942
+ array(
943
+ 'type' => 'button',
944
+ 'option' => $option_name,
945
+ 'field' => $field,
946
+ 'value' => __( 'Download now', 'ip-geo-block' ),
947
+ 'disabled' => empty( $providers ),
948
+ 'after' => '<div id="ip-geo-block-download"></div>',
949
+ )
950
+ );
951
+
952
+ /*----------------------------------------*
953
+ * Record settings
954
+ *----------------------------------------*/
955
+ $section = $plugin_slug . '-recording';
956
+ add_settings_section(
957
+ $section,
958
+ __( 'Record settings', 'ip-geo-block' ),
959
+ NULL,
960
+ $option_slug
961
+ );
962
+
963
+ // Record validation statistics
964
+ $field = 'save_statistics';
965
+ add_settings_field(
966
+ $option_name.'_'.$field,
967
+ __( 'Record validation statistics', 'ip-geo-block' ),
968
+ array( $context, 'callback_field' ),
969
+ $option_slug,
970
+ $section,
971
+ array(
972
+ 'type' => 'checkbox',
973
+ 'option' => $option_name,
974
+ 'field' => $field,
975
+ 'value' => $options[ $field ],
976
+ )
977
+ );
978
+
979
+ // Record validation logs
980
+ $field = 'validation';
981
+ add_settings_field(
982
+ $option_name.'_'.$field.'_reclogs',
983
+ __( 'Record validation logs', 'ip-geo-block' ),
984
+ array( $context, 'callback_field' ),
985
+ $option_slug,
986
+ $section,
987
+ array(
988
+ 'type' => 'select',
989
+ 'option' => $option_name,
990
+ 'field' => $field,
991
+ 'sub-field' => 'reclogs',
992
+ 'value' => $options[ $field ]['reclogs'],
993
+ 'list' => array(
994
+ 0 => __( 'Disable', 'ip-geo-block' ),
995
+ 1 => __( 'Only when blocked', 'ip-geo-block' ),
996
+ 2 => __( 'Only when passed', 'ip-geo-block' ),
997
+ 3 => __( 'Unauthenticated user', 'ip-geo-block' ),
998
+ 4 => __( 'Authenticated user', 'ip-geo-block' ),
999
+ 5 => __( 'All of validation', 'ip-geo-block' ),
1000
+ ),
1001
+ )
1002
+ );
1003
+
1004
+ if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ):
1005
+ $key = 'recdays';
1006
+ add_settings_field(
1007
+ $option_name.'_'.$field.'_'.$key,
1008
+ __( 'Recording period of the logs (days)', 'ip-geo-block' ),
1009
+ array( $context, 'callback_field' ),
1010
+ $option_slug,
1011
+ $section,
1012
+ array(
1013
+ 'type' => 'text',
1014
+ 'option' => $option_name,
1015
+ 'field' => $field,
1016
+ 'sub-field' => $key,
1017
+ 'value' => $options[ $field ][ $key ],
1018
+ )
1019
+ );
1020
+
1021
+ $key = 'maxlogs';
1022
+ add_settings_field(
1023
+ $option_name.'_'.$field.'_'.$key,
1024
+ __( 'Maximum length of logs for each target', 'ip-geo-block' ),
1025
+ array( $context, 'callback_field' ),
1026
+ $option_slug,
1027
+ $section,
1028
+ array(
1029
+ 'type' => 'text',
1030
+ 'option' => $option_name,
1031
+ 'field' => $field,
1032
+ 'sub-field' => $key,
1033
+ 'value' => $options[ $field ][ $key ],
1034
+ )
1035
+ );
1036
+ endif;
1037
+
1038
+ // $_POST keys to be recorded with their values in logs
1039
+ add_settings_field(
1040
+ $option_name.'_'.$field.'_postkey',
1041
+ __( '<dfn title="e.g. action, comment, log, pwd">$_POST keys to be recorded with their values in logs</dfn>', 'ip-geo-block' ),
1042
+ array( $context, 'callback_field' ),
1043
+ $option_slug,
1044
+ $section,
1045
+ array(
1046
+ 'type' => 'text',
1047
+ 'option' => $option_name,
1048
+ 'field' => $field,
1049
+ 'sub-field' => 'postkey',
1050
+ 'value' => $options[ $field ]['postkey'],
1051
+ 'after' => $comma[0],
1052
+ )
1053
+ );
1054
+
1055
+ // Anonymize IP address
1056
+ $field = 'anonymize';
1057
+ add_settings_field(
1058
+ $option_name.'_'.$field,
1059
+ __( '<dfn title="e.g. 123.456.789.***">Anonymize IP address</dfn>', 'ip-geo-block' ),
1060
+ array( $context, 'callback_field' ),
1061
+ $option_slug,
1062
+ $section,
1063
+ array(
1064
+ 'type' => 'checkbox',
1065
+ 'option' => $option_name,
1066
+ 'field' => $field,
1067
+ 'value' => ! empty( $options[ $field ] ) ? TRUE : FALSE,
1068
+ )
1069
+ );
1070
+
1071
+ /*----------------------------------------*
1072
+ * Cache settings
1073
+ *----------------------------------------*/
1074
+ $section = $plugin_slug . '-cache';
1075
+ add_settings_section(
1076
+ $section,
1077
+ __( 'IP address cache settings', 'ip-geo-block' ),
1078
+ NULL,
1079
+ $option_slug
1080
+ );
1081
+
1082
+ // Expiration time [sec]
1083
+ $field = 'cache_time';
1084
+ add_settings_field(
1085
+ $option_name.'_'.$field,
1086
+ sprintf( __( '<dfn title="If user authentication fails consecutively %d times, subsequent login will also be prohibited for this and garbage collection period.">Expiration time [sec]</dfn>', 'ip-geo-block' ), (int)$options['login_fails'] ),
1087
+ array( $context, 'callback_field' ),
1088
+ $option_slug,
1089
+ $section,
1090
+ array(
1091
+ 'type' => 'text',
1092
+ 'option' => $option_name,
1093
+ 'field' => $field,
1094
+ 'value' => $options[ $field ],
1095
+ )
1096
+ );
1097
+
1098
+ // Garbage collection period [sec]
1099
+ $field = 'cache_time_gc';
1100
+ add_settings_field(
1101
+ $option_name.'_'.$field,
1102
+ __( 'Garbage collection period [sec]', 'ip-geo-block' ),
1103
+ array( $context, 'callback_field' ),
1104
+ $option_slug,
1105
+ $section,
1106
+ array(
1107
+ 'type' => 'text',
1108
+ 'option' => $option_name,
1109
+ 'field' => $field,
1110
+ 'value' => $options[ $field ],
1111
+ )
1112
+ );
1113
+
1114
+ if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ):
1115
+ // Number of entries
1116
+ $field = 'cache_hold';
1117
+ add_settings_field(
1118
+ $option_name.'_'.$field,
1119
+ __( 'Number of entries to be displayed in cache', 'ip-geo-block' ),
1120
+ array( $context, 'callback_field' ),
1121
+ $option_slug,
1122
+ $section,
1123
+ array(
1124
+ 'type' => 'text',
1125
+ 'option' => $option_name,
1126
+ 'field' => $field,
1127
+ 'value' => $options[ $field ],
1128
+ )
1129
+ );
1130
+ endif;
1131
+
1132
+ /*----------------------------------------*
1133
+ * Submission settings
1134
+ *----------------------------------------*/
1135
+ $section = $plugin_slug . '-submission';
1136
+ add_settings_section(
1137
+ $section,
1138
+ __( 'Submission settings', 'ip-geo-block' ),
1139
+ NULL,
1140
+ $option_slug
1141
+ );
1142
+
1143
+ $val = $GLOBALS['allowedtags'];
1144
+ unset( $val['blockquote'] );
1145
+
1146
+ // Message on comment form
1147
+ $field = 'comment';
1148
+ add_settings_field(
1149
+ $option_name.'_'.$field,
1150
+ '<dfn title="' . __( 'The whole will be wrapped by &lt;p&gt; tag. Allowed tags: ', 'ip-geo-block' ) . implode( ', ', array_keys( $val ) ) . '">' . __( 'Message on comment form', 'ip-geo-block' ) . '</dfn>',
1151
+ array( $context, 'callback_field' ),
1152
+ $option_slug,
1153
+ $section,
1154
+ array(
1155
+ 'type' => 'select-text',
1156
+ 'option' => $option_name,
1157
+ 'field' => $field,
1158
+ 'sub-field' => 'pos',
1159
+ 'txt-field' => 'msg',
1160
+ 'value' => $options[ $field ]['pos'],
1161
+ 'list' => array(
1162
+ 0 => __( 'None', 'ip-geo-block' ),
1163
+ 1 => __( 'Top', 'ip-geo-block' ),
1164
+ 2 => __( 'Bottom', 'ip-geo-block' ),
1165
+ ),
1166
+ 'text' => $options[ $field ]['msg'], // escaped by esc_attr() at 'text'
1167
+ )
1168
+ );
1169
+
1170
+ /*----------------------------------------*
1171
+ * Plugin settings
1172
+ *----------------------------------------*/
1173
+ $section = $plugin_slug . '-others';
1174
+ add_settings_section(
1175
+ $section,
1176
+ __( 'Plugin settings', 'ip-geo-block' ),
1177
+ NULL,
1178
+ $option_slug
1179
+ );
1180
+
1181
+ // Remove all settings at uninstallation
1182
+ $field = 'clean_uninstall';
1183
+ add_settings_field(
1184
+ $option_name.'_'.$field,
1185
+ __( 'Remove all settings at uninstallation', 'ip-geo-block' ),
1186
+ array( $context, 'callback_field' ),
1187
+ $option_slug,
1188
+ $section,
1189
+ array(
1190
+ 'type' => 'checkbox',
1191
+ 'option' => $option_name,
1192
+ 'field' => $field,
1193
+ 'value' => $options[ $field ],
1194
+ )
1195
+ );
1196
+
1197
+ // Google Maps API key
1198
+ $field = 'api_key';
1199
+ $key = 'GoogleMap';
1200
+ if ( 'default' !== $options[ $field ][ $key ] or defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ) {
1201
+ add_settings_field(
1202
+ $option_name.'_'.$field,
1203
+ __( '<dfn title="Valid key for Google Maps JavaScript API">Google Maps API key</dfn>', 'ip-geo-block' ),
1204
+ array( $context, 'callback_field' ),
1205
+ $option_slug,
1206
+ $section,
1207
+ array(
1208
+ 'type' => 'text',
1209
+ 'option' => $option_name,
1210
+ 'field' => $field,
1211
+ 'sub-field' => $key,
1212
+ 'value' => $options[ $field ][ $key ],
1213
+ )
1214
+ );
1215
+ }
1216
+
1217
+ $desc = __( 'You need to click the &#8220;Save Changes&#8221; button for imported settings to take effect.', 'ip-geo-block' );
1218
+
1219
+ // Export / Import settings
1220
+ $field = 'export-import';
1221
+ add_settings_field(
1222
+ $option_name.'_'.$field,
1223
+ sprintf( '<dfn title="%s">' . __( 'Export / Import settings', 'ip-geo-block' ) . '</dfn>', $desc ),
1224
+ array( $context, 'callback_field' ),
1225
+ $option_slug,
1226
+ $section,
1227
+ array(
1228
+ 'type' => 'none',
1229
+ 'before' =>
1230
+ '<a class="button button-secondary" id="ip-geo-block-export" title="' . __( 'Export to the local file', 'ip-geo-block' ) . '" href="javascript:void(0)">'. __( 'Export settings', 'ip-geo-block' ) . '</a>&nbsp;' .
1231
+ '<a class="button button-secondary" id="ip-geo-block-import" title="' . __( 'Import from the local file', 'ip-geo-block' ) . '" href="javascript:void(0)">'. __( 'Import settings', 'ip-geo-block' ) . '</a>',
1232
+ 'after' => '<div id="ip-geo-block-export-import"></div>',
1233
+ )
1234
+ );
1235
+
1236
+ // Pre-defined settings
1237
+ $field = 'pre-defined';
1238
+ add_settings_field(
1239
+ $option_name.'_'.$field,
1240
+ sprintf( '<dfn title="%s">' . __( 'Import pre-defined settings', 'ip-geo-block' ) . '</dfn>', $desc ),
1241
+ array( $context, 'callback_field' ),
1242
+ $option_slug,
1243
+ $section,
1244
+ array(
1245
+ 'type' => 'none',
1246
+ 'before' =>
1247
+ '<a class="button button-secondary" id="ip-geo-block-default" title="' . __( 'Import the default settings to revert to the &#8220;Right after installing&#8221; state', 'ip-geo-block' ) . '" href="javascript:void(0)">' . __( 'Default settings', 'ip-geo-block' ) . '</a>&nbsp;' .
1248
+ '<a class="button button-secondary" id="ip-geo-block-preferred" title="' . __( 'Import the preferred settings mainly for the &#8220;Validation target settings&#8221;', 'ip-geo-block' ) . '" href="javascript:void(0)">' . __( 'Best settings', 'ip-geo-block' ) . '</a>',
1249
+ 'after' => '<div id="ip-geo-block-pre-defined"></div>',
1250
+ )
1251
+ );
1252
+
1253
+ // Show WordPress installation info
1254
+ $field = 'show-info';
1255
+ add_settings_field(
1256
+ $option_name.'_'.$field,
1257
+ __( '<dfn title="Please copy &amp; paste when submitting your issue to support forum.">Installation information</dfn><br />[ <a rel="noreferrer" href="https://wordpress.org/support/plugin/ip-geo-block" title="WordPress &#8250; Support &raquo; IP Geo Block">support forum</a> ]', 'ip-geo-block' ),
1258
+ array( $context, 'callback_field' ),
1259
+ $option_slug,
1260
+ $section,
1261
+ array(
1262
+ 'type' => 'none',
1263
+ 'before' =>
1264
+ '<a class="button button-secondary" id="ip-geo-block-show-info" title="' . __( 'Show PHP, WordPress, theme and plugins information.', 'ip-geo-block' ) . '" href="javascript:void(0)">' . __( 'Show information', 'ip-geo-block' ) . '</a>&nbsp;',
1265
+ 'after' => '<div id="ip-geo-block-wp-info"></div>',
1266
+ )
1267
+ );
1268
+
1269
+ if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ):
1270
+ // Manipulate DB table for validation logs
1271
+ $field = 'delete_table';
1272
+ add_settings_field(
1273
+ $option_name.'_'.$field,
1274
+ __( 'Delete DB table for validation logs', 'ip-geo-block' ),
1275
+ array( $context, 'callback_field' ),
1276
+ $option_slug,
1277
+ $section,
1278
+ array(
1279
+ 'type' => 'button',
1280
+ 'option' => $option_name,
1281
+ 'field' => $field,
1282
+ 'value' => __( 'Delete now', 'ip-geo-block' ),
1283
+ 'after' => '<div id="ip-geo-block-delete-table"></div>',
1284
+ )
1285
+ );
1286
+
1287
+ $field = 'create_table';
1288
+ add_settings_field(
1289
+ $option_name.'_'.$field,
1290
+ __( 'Create DB table for validation logs', 'ip-geo-block' ),
1291
+ array( $context, 'callback_field' ),
1292
+ $option_slug,
1293
+ $section,
1294
+ array(
1295
+ 'type' => 'button',
1296
+ 'option' => $option_name,
1297
+ 'field' => $field,
1298
+ 'value' => __( 'Create now', 'ip-geo-block' ),
1299
+ 'after' => '<div id="ip-geo-block-create-table"></div>',
1300
+ )
1301
+ );
1302
+ endif;
1303
+
1304
+ }
1305
+
1306
+ /**
1307
+ * Subsidiary note
1308
+ *
1309
+ */
1310
+ public static function note_target() {
1311
+ echo
1312
+ '<ul class="ip-geo-block-note">', "\n",
1313
+ '<li>', __( 'To enhance the protection ability, please refer to &#8220;<a rel="noreferrer" href="http://www.ipgeoblock.com/codex/the-best-practice-for-target-settings.html" title="The best practice for target settings | IP Geo Block">The best practice for target settings</a>&#8221;.', 'ip-geo-block' ), '</li>', "\n",
1314
+ '<li>', __( 'If you have any troubles with these, please check FAQ at <a rel="noreferrer" href="https://wordpress.org/plugins/ip-geo-block/faq/" title="IP Geo Block &mdash; WordPress Plugins">WordPress.org</a> and <a rel="noreferrer" href="http://www.ipgeoblock.com/codex/#faq" title="Codex | IP Geo Block">Codex</a>.', 'ip-geo-block' ), '</li>', "\n",
1315
+ '</ul>', "\n";
1316
+ }
1317
+
1318
+ public static function note_services() {
1319
+ echo
1320
+ '<ul class="ip-geo-block-note">', "\n",
1321
+ '<li>', __( 'While Maxmind and IP2Location will fetch the local database, others will pass an IP address to the APIs via HTTP.', 'ip-geo-block' ), '</li>', "\n",
1322
+ '<li>', __( 'Please select the appropriate APIs to fit the privacy law in your country.', 'ip-geo-block' ), '</li>', "\n",
1323
+ '</ul>', "\n";
1324
+ }
1325
+
1326
+ public static function note_public() {
1327
+ echo
1328
+ '<ul class="ip-geo-block-note">', "\n",
1329
+ '<li>', __( 'Please refer to the document &#8220;<a rel="noreferrer" href="http://www.ipgeoblock.com/codex/#blocking-on-front-end" title="Codex | IP Geo Block">Blocking on front-end</a>&#8221; for details, including restrictions on cache plugin.', 'ip-geo-block' ), '</li>', "\n",
1330
+ '<li>', __( 'If you find any issues or have something to suggest, please feel free to open an issue at <a rel="noreferrer" href="https://wordpress.org/support/plugin/ip-geo-block" title="WordPress &#8250; Support &raquo; IP Geo Block">support forum</a>.', 'ip-geo-block' ), '</li>', "\n",
1331
+ '</ul>', "\n";
1332
+ }
1333
+
1334
+ }
admin/includes/tab-statistics.php ADDED
@@ -0,0 +1,290 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class IP_Geo_Block_Admin_Tab {
3
+
4
+ public static function tab_setup( $context ) {
5
+ $plugin_slug = IP_Geo_Block::PLUGIN_NAME;
6
+ $option_slug = IP_Geo_Block::PLUGIN_NAME;
7
+ $option_name = IP_Geo_Block::OPTION_NAME;
8
+ $options = IP_Geo_Block::get_option();
9
+ $statistics = IP_Geo_Block_Logs::restore_stat( TRUE );
10
+
11
+ register_setting(
12
+ $option_slug,
13
+ $option_name
14
+ );
15
+
16
+ if ( $options['save_statistics'] ) :
17
+
18
+ /*----------------------------------------*
19
+ * Statistics of comment post
20
+ *----------------------------------------*/
21
+ $section = $plugin_slug . '-statistics';
22
+ add_settings_section(
23
+ $section,
24
+ __( 'Statistics of validation', 'ip-geo-block' ),
25
+ NULL,
26
+ $option_slug
27
+ );
28
+
29
+ // Number of blocked access
30
+ $field = 'blocked';
31
+ add_settings_field(
32
+ $option_name.'_'.$field,
33
+ __( 'Blocked', 'ip-geo-block' ),
34
+ array( $context, 'callback_field' ),
35
+ $option_slug,
36
+ $section,
37
+ array(
38
+ 'type' => 'html',
39
+ 'option' => $option_name,
40
+ 'field' => $field,
41
+ 'value' => esc_html( $statistics[ $field ] ),
42
+ )
43
+ );
44
+
45
+ // Blocked by countries
46
+ $field = 'countries';
47
+ $html = '<div id="'.$plugin_slug.'-chart-countries"></div>';
48
+ $html .= '<ul id="'.$plugin_slug.'-countries" class="'.$option_slug.'-'.$field.'">';
49
+
50
+ arsort( $statistics['countries'] );
51
+ foreach ( $statistics['countries'] as $key => $val ) {
52
+ $html .= sprintf( '<li>%2s:%5d</li>', esc_html( $key ), (int)$val );
53
+ }
54
+
55
+ $html .= '</ul>';
56
+
57
+ add_settings_field(
58
+ $option_name.'_'.$field,
59
+ __( 'Blocked by countries', 'ip-geo-block' ),
60
+ array( $context, 'callback_field' ),
61
+ $option_slug,
62
+ $section,
63
+ array(
64
+ 'type' => 'html',
65
+ 'option' => $option_name,
66
+ 'field' => $field,
67
+ 'value' => $html,
68
+ )
69
+ );
70
+
71
+ // Blocked on a daily basis
72
+ $field = 'daily';
73
+ $html = '<div id="'.$plugin_slug.'-chart-daily"><table id="'.$plugin_slug.'-targets">';
74
+
75
+ $prev = 0;
76
+ $targets = array( 'comment', 'xmlrpc', 'login', 'admin', 'public' );
77
+ foreach ( $statistics['daystats'] as $key => $val ) {
78
+ while( $prev && $key - $prev > DAY_IN_SECONDS ) {
79
+ $prev += DAY_IN_SECONDS;
80
+ $html .= '<tr><td>' . IP_Geo_Block_Util::localdate( $prev, 'Y-m-d' ) . '</td>'; // must be ISO 8601 or RFC 2822
81
+ foreach ( $targets as $target ) {
82
+ $html .= '<td>0</td>';
83
+ }
84
+ }
85
+ $prev = $key;
86
+ $html .= '<tr><td>' . date( 'Y-m-d', $key ) . '</td>'; // must be ISO 8601 or RFC 2822
87
+ foreach ( $targets as $target ) {
88
+ $html .= '<td>' . (isset( $val[ $target ] ) ? (int)$val[ $target ] : 0) . '</td>';
89
+ }
90
+ $html .= '</tr>';
91
+ }
92
+
93
+ $html .= '</table></div>';
94
+
95
+ add_settings_field(
96
+ $option_name.'_'.$field,
97
+ __( 'Blocked per day', 'ip-geo-block' ),
98
+ array( $context, 'callback_field' ),
99
+ $option_slug,
100
+ $section,
101
+ array(
102
+ 'type' => 'html',
103
+ 'option' => $option_name,
104
+ 'field' => $field,
105
+ 'value' => $html,
106
+ )
107
+ );
108
+
109
+ // Blocked by type of IP address
110
+ $field = 'type';
111
+ add_settings_field(
112
+ $option_name.'_'.$field,
113
+ __( 'Blocked by type of IP address', 'ip-geo-block' ),
114
+ array( $context, 'callback_field' ),
115
+ $option_slug,
116
+ $section,
117
+ array(
118
+ 'type' => 'html',
119
+ 'option' => $option_name,
120
+ 'field' => $field,
121
+ 'value' => '<table class="'.$option_slug.'-statistics-table">' .
122
+ '<thead><tr><th>IPv4</th><th>IPv6</th></tr></thead><tbody><tr>' .
123
+ '<td>' . esc_html( $statistics['IPv4'] ) . '</td>' .
124
+ '<td>' . esc_html( $statistics['IPv6'] ) . '</td>' .
125
+ '</tr></tbody></table>',
126
+ )
127
+ );
128
+
129
+ $field = 'service';
130
+ $html = '<table class="'.$option_slug.'-statistics-table"><thead><tr>';
131
+ $html .= '<th>' . __( 'Name of API', 'ip-geo-block' ) . '</th>';
132
+ $html .= '<th>' . __( 'Calls', 'ip-geo-block' ) . '</th>';
133
+ $html .= '<th>' . __( 'Response [msec]', 'ip-geo-block' ) . '</th>';
134
+ $html .= '</tr></thead><tbody>';
135
+
136
+ foreach ( $statistics['providers'] as $key => $val ) {
137
+ $html .= '<tr><td>' . esc_html( $key ) . '</td>';
138
+ $html .= '<td>' . sprintf( '%5d', (int)$val['count'] ) . '</td><td>';
139
+ $html .= sprintf( '%4.1f', (float)(1000.0 * $val['time'] / $val['count']) );
140
+ $html .= '</td></tr>';
141
+ }
142
+ $html .= "</tbody></table>";
143
+
144
+ // Average response time of each API
145
+ add_settings_field(
146
+ $option_name.'_'.$field,
147
+ __( 'Average response time of each API', 'ip-geo-block' ),
148
+ array( $context, 'callback_field' ),
149
+ $option_slug,
150
+ $section,
151
+ array(
152
+ 'type' => 'html',
153
+ 'option' => $option_name,
154
+ 'field' => $field,
155
+ 'value' => $html,
156
+ )
157
+ );
158
+
159
+ // Clear statistics
160
+ $field = 'clear_statistics';
161
+ add_settings_field(
162
+ $option_name.'_'.$field,
163
+ __( 'Clear statistics', 'ip-geo-block' ),
164
+ array( $context, 'callback_field' ),
165
+ $option_slug,
166
+ $section,
167
+ array(
168
+ 'type' => 'button',
169
+ 'option' => $option_name,
170
+ 'field' => $field,
171
+ 'value' => __( 'Clear now', 'ip-geo-block' ),
172
+ 'after' => '<div id="'.$plugin_slug.'-statistics"></div>',
173
+ )
174
+ );
175
+
176
+ else:
177
+
178
+ /*----------------------------------------*
179
+ * Warning
180
+ *----------------------------------------*/
181
+ $section = $plugin_slug . '-statistics';
182
+ add_settings_section(
183
+ $section,
184
+ __( 'Statistics of validation', 'ip-geo-block' ),
185
+ array( __CLASS__, 'warn_statistics' ),
186
+ $option_slug
187
+ );
188
+
189
+ $field = 'warning';
190
+ add_settings_field(
191
+ $option_name.'_'.$field,
192
+ '&hellip;',
193
+ array( $context, 'callback_field' ),
194
+ $option_slug,
195
+ $section,
196
+ array(
197
+ 'type' => 'none',
198
+ 'after' => '&hellip;',
199
+ )
200
+ );
201
+
202
+ endif;
203
+
204
+ /*----------------------------------------*
205
+ * Statistics of cache
206
+ *----------------------------------------*/
207
+ $section = $plugin_slug . '-cache';
208
+ add_settings_section(
209
+ $section,
210
+ __( 'Statistics of cache', 'ip-geo-block' ),
211
+ NULL, // array( $context, 'callback_cache_stat' ),
212
+ $option_slug
213
+ );
214
+
215
+ $field = 'cache';
216
+ $html = '<table class="'.$option_slug.'-statistics-table"><thead><tr>';
217
+ $html .= '<th>' . __( 'IP address', 'ip-geo-block' ) . '</th>';
218
+ $html .= '<th>' . __( 'Country code / Access', 'ip-geo-block' ) . '</th>';
219
+ $html .= '<th>' . __( 'Elapsed [sec] / Calls', 'ip-geo-block' ) . '</th>';
220
+ $html .= '</tr></thead><tbody>';
221
+
222
+ if ( $cache = IP_Geo_Block_API_Cache::get_cache_all() ) {
223
+ $count = 0;
224
+ $time = time();
225
+ $debug = defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG;
226
+ foreach ( $cache as $key => $val ) {
227
+ if ( $options['anonymize'] )
228
+ $key = preg_replace( '/\d{1,3}$/', '***', $key );
229
+ $html .= '<tr><td>' . esc_html( $key ) . '</td>';
230
+ $html .= '<td>' . esc_html( $val['code'] ) . ' / ';
231
+ $html .= '<small>' . esc_html( $val['hook'] ) . '</small></td>';
232
+ $html .= '<td>' . ( $time - (int)$val['time'] ) . ' / ';
233
+ $html .= $options['save_statistics'] ? (int)$val['call'] : '-';
234
+ if ( $debug ) {
235
+ $user = get_user_by( 'id', intval( $val['auth'] ) );
236
+ $html .= ' ' . esc_html( $user ? $user->get( 'user_login' ) : '' );
237
+ $html .= ' / fail:' . intval( $val['fail'] );
238
+ }
239
+ $html .= '</td></tr>';
240
+ if ( ++$count >= $options['cache_hold'] )
241
+ break;
242
+ }
243
+ }
244
+
245
+ $html .= '</tbody></table>';
246
+
247
+ if ( ! empty( $count ) )
248
+ $html .= '<p style="text-align:right">[ ' . $count . ' / ' . count( $cache ) . ' ]</p>';
249
+
250
+ add_settings_field(
251
+ $option_name.'_'.$field,
252
+ __( 'IP address in cache', 'ip-geo-block' ),
253
+ array( $context, 'callback_field' ),
254
+ $option_slug,
255
+ $section,
256
+ array(
257
+ 'type' => 'html',
258
+ 'option' => $option_name,
259
+ 'field' => $field,
260
+ 'value' => $html,
261
+ )
262
+ );
263
+
264
+ $field = 'clear_cache';
265
+ add_settings_field(
266
+ $option_name.'_'.$field,
267
+ __( 'Clear cache', 'ip-geo-block' ),
268
+ array( $context, 'callback_field' ),
269
+ $option_slug,
270
+ $section,
271
+ array(
272
+ 'type' => 'button',
273
+ 'option' => $option_name,
274
+ 'field' => $field,
275
+ 'value' => __( 'Clear now', 'ip-geo-block' ),
276
+ 'after' => '<div id="'.$plugin_slug.'-cache"></div>',
277
+ )
278
+ );
279
+ }
280
+
281
+ /**
282
+ * Function that fills the section with the desired content.
283
+ *
284
+ */
285
+ public static function warn_statistics() {
286
+ echo '<p>', __( 'Current setting of [<strong>Record validation statistics</strong>] on [<strong>Settings</strong>] tab is not selected [<strong>Enable</strong>].', 'ip-geo-block' ), '</p>', "\n";
287
+ echo '<p>', __( 'Please set the proper condition to record and analyze the validation statistics.', 'ip-geo-block' ), '</p>', "\n";
288
+ }
289
+
290
+ }
admin/js/admin.js ADDED
@@ -0,0 +1,949 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*jslint white: true */
2
+ /*!
3
+ * Project: WordPress IP Geo Block
4
+ * Copyright (c) 2015-2016 tokkonopapa (tokkonopapa@yahoo.com)
5
+ * This software is released under the MIT License.
6
+ */
7
+ var ip_geo_block_time = new Date();
8
+
9
+ (function ($, window, document) {
10
+ 'use strict';
11
+
12
+ function ID(selector, id) {
13
+ var keys = {
14
+ '.': '.ip-geo-block-',
15
+ '#': '#ip-geo-block-',
16
+ '@': '#ip_geo_block_settings_',
17
+ '$': 'ip-geo-block-',
18
+ '%': 'ip_geo_block_'
19
+ };
20
+ return 'undefined' !== typeof id ? keys[selector] + id : keys.$ + selector;
21
+ }
22
+
23
+ function sanitize(str) {
24
+ return str ? str.toString().replace(/[&<>"']/g, function (match) {
25
+ return {
26
+ '&': '&amp;',
27
+ '<': '&lt;',
28
+ '>': '&gt;',
29
+ '"': '&quot;',
30
+ "'": '&#39;'
31
+ }[match];
32
+ }) : '';
33
+ }
34
+
35
+ function loading(id, flag) {
36
+ if (flag) {
37
+ $(ID('#', id)).addClass(ID('loading'));
38
+ } else {
39
+ $(ID('#', id)).removeClass(ID('loading'));
40
+ }
41
+ }
42
+
43
+ function confirm(msg, callback) {
44
+ if (window.confirm(sanitize(msg))) {
45
+ callback();
46
+ }
47
+ }
48
+
49
+ function warning(status, msg) {
50
+ window.alert(status ? sanitize(status + ': ' + msg) : sanitize(msg));
51
+ }
52
+
53
+ function notice_html5() {
54
+ warning(null, IP_GEO_BLOCK.msg[6]);
55
+ }
56
+
57
+ function redirect(page, tab) {
58
+ if (-1 !== location.href.indexOf(page)) {
59
+ var url = sanitize(page) + (tab ? '&' + sanitize(tab) : '');
60
+ if (typeof IP_GEO_BLOCK_ZEP === 'undefined') {
61
+ window.location.href = url;
62
+ } else {
63
+ IP_GEO_BLOCK_ZEP.redirect(url);
64
+ }
65
+ }
66
+ }
67
+
68
+ function ajax_post(id, request, callback, objs) {
69
+ if (id) {
70
+ loading(id, true);
71
+ }
72
+
73
+ request.action = IP_GEO_BLOCK.action;
74
+ request.nonce = IP_GEO_BLOCK.nonce;
75
+
76
+ $.post(IP_GEO_BLOCK.url, request)
77
+
78
+ .done(function (data, textStatus, jqXHR) {
79
+ callback(data);
80
+ })
81
+
82
+ .fail(function (jqXHR, textStatus, errorThrown) {
83
+ warning(textStatus, jqXHR.responseText);
84
+ })
85
+
86
+ .always(function () {
87
+ if (id) {
88
+ if (objs) {
89
+ $.when.apply($, objs).then(function () {
90
+ loading(id, false);
91
+ });
92
+ } else {
93
+ loading(id, false);
94
+ }
95
+ }
96
+ });
97
+ }
98
+
99
+ // Clear statistics, cache, logs
100
+ function ajax_clear(cmd, type) {
101
+ ajax_post(cmd, {
102
+ cmd: 'clear-' + cmd,
103
+ which: type
104
+ }, function (data) {
105
+ redirect(data.page, data.tab);
106
+ });
107
+ }
108
+
109
+ // Manipulate DB table for validation logs
110
+ function ajax_table(cmd) {
111
+ ajax_post(cmd, {
112
+ cmd: cmd
113
+ }, function (data) {
114
+ redirect(data.page, data.tab);
115
+ });
116
+ }
117
+
118
+ // Show/Hide description of WP-ZEP
119
+ function show_description(select) {
120
+ var data, desc = ID('.', 'desc');
121
+ select.next(desc).empty();
122
+ data = select.children('option:selected').data('desc');
123
+ if (data) {
124
+ select.next(desc).html($.parseHTML(data)); // jQuery 1.8+
125
+ }
126
+ }
127
+
128
+ // Show/Hide folding list
129
+ function show_folding_list($this, element, field, mask) {
130
+ var stat = false;
131
+ stat |= (0 === $this.prop('type').indexOf('checkbox') && $this.is(':checked'));
132
+ stat |= (0 === $this.prop('type').indexOf('select' ) && '0' !== $this.val());
133
+
134
+ element.nextAll('.' + field + '_folding').each(function (i, obj) {
135
+ obj = $(obj);
136
+
137
+ // completely hide
138
+ // obj.css('display', mask ? 'block' : 'none');
139
+
140
+ // fold the contents
141
+ if (stat && mask) {
142
+ obj.removeClass('folding-disable');
143
+ } else {
144
+ obj.children('li').hide();
145
+ obj.addClass('folding-disable');
146
+ obj.removeClass(ID('dropdown')).addClass(ID('dropup'));
147
+ }
148
+ });
149
+ }
150
+
151
+ // Encode/Decode to prevent blocking before post ajax
152
+ function base64_encode(str) {
153
+ return window.btoa(str);
154
+ }
155
+
156
+ function base64_decode(str) {
157
+ return window.atob(str);
158
+ }
159
+
160
+ // Equivalent for PHP's str_rot13
161
+ // @link http://phpjs.org/functions/str_rot13/
162
+ function str_rot13(str) {
163
+ return String(str).replace(/[a-z]/gi, function (s) {
164
+ return String.fromCharCode(s.charCodeAt(0) + (s.toLowerCase() < 'n' ? 13 : -13)); //'
165
+ });
166
+ }
167
+
168
+ // Wrapper for encode/decode strings
169
+ function encode_str(str) {
170
+ return base64_encode(str_rot13(str));
171
+ }
172
+
173
+ function decode_str(str) {
174
+ return str_rot13(base64_decode(str));
175
+ }
176
+
177
+ // File Reader
178
+ function readfile(file, callback) {
179
+ var reader = new FileReader();
180
+ reader.onload = function (event) {
181
+ if (callback) {
182
+ callback(event.target.result);
183
+ }
184
+ };
185
+ reader.onerror = function (event) {
186
+ warning('Error', event.target.error.code);
187
+ };
188
+ reader.readAsText(file);
189
+ }
190
+
191
+ // Enable / Disable at front-end target settings
192
+ function set_front_end($this) {
193
+ var field = ID('%', 'settings'),
194
+ checked = $this.is(':checked'),
195
+ select = $(ID('@', 'public_target_rule')),
196
+ parent = $this.closest('tr').nextAll('tr');
197
+
198
+ // Enable / Disable descendent items
199
+ parent.find('[name^="' + field + '"]').prop('disabled', !checked);
200
+
201
+ // Enable / Disable description
202
+ parent.find(ID('.', 'desc')).css('opacity', checked ? 1.0 : 0.5);
203
+
204
+ // Show / Hide validation target
205
+ show_folding_list($this, select, field, '1' === select.val() ? true : false);
206
+ }
207
+
208
+ /**
209
+ * jQuery deserialize plugin based on https://gist.github.com/nissuk/835256
210
+ *
211
+ * usage: $('form').deserialize({'name':'value', ...});
212
+ */
213
+ $.fn.deserialize = function (json, options) {
214
+ return this.each(function () {
215
+ var key, name, value,
216
+ self = this,
217
+ data = {};
218
+
219
+ for (key in json) {
220
+ if(json.hasOwnProperty(key)) {
221
+ name = decodeURIComponent(key);
222
+ value = decodeURIComponent(json[key]);
223
+
224
+ if (!(name in data)) { // !data.hasOwnProperty(name)
225
+ data[name] = [];
226
+ }
227
+
228
+ data[name].push(value);
229
+ }
230
+ }
231
+
232
+ $.each(data, function (name, val) {
233
+ $('[name="' + name + '"]:input', self).val(val);
234
+ });
235
+ });
236
+ };
237
+
238
+ function deserialize_json(json) {
239
+ if (json) {
240
+ // Set fields on form
241
+ if ('string' === typeof json) {
242
+ json = JSON.parse(json);
243
+ }
244
+
245
+ // deserialize to the form
246
+ $(ID('#', 'import')).closest('form').deserialize(json);
247
+
248
+ // Help text
249
+ $.each(['matching_rule', 'validation_login', 'validation_plugins', 'validation_themes'], function (i, key) {
250
+ $(ID('@', key)).trigger('change');
251
+ });
252
+
253
+ // Public facing pages
254
+ set_front_end($(ID('@', 'validation_public')));
255
+
256
+ // Additional edge case
257
+ var i = ID('%', 'settings[providers][IPInfoDB]');
258
+ $(ID('@', 'providers_IPInfoDB')).prop('checked', json[i] ? true : false);
259
+ }
260
+ }
261
+
262
+ // google chart
263
+ var chart = {
264
+ self: this,
265
+ drawChart: function () {
266
+ this.drawPie();
267
+ this.drawLine();
268
+ },
269
+
270
+ // Pie Chart
271
+ dataPie: null,
272
+ viewPie: null,
273
+ drawPie: function () {
274
+ if (!self.dataPie) {
275
+ self.dataPie = new google.visualization.DataTable();
276
+ self.dataPie.addColumn('string', 'Country');
277
+ self.dataPie.addColumn('number', 'Requests');
278
+ var value;
279
+ $(ID('#', 'countries li')).each(function () {
280
+ value = $(this).text().split(':');
281
+ self.dataPie.addRow([value[0] || '', Number(value[1])]);
282
+ });
283
+ }
284
+ if (!self.viewPie) {
285
+ self.viewPie = new google.visualization.PieChart(
286
+ document.getElementById(ID('chart-countries'))
287
+ );
288
+ }
289
+ if ($(ID('#', 'chart-countries')).width()) {
290
+ self.viewPie.draw(self.dataPie, {
291
+ backgroundColor: '#f1f1f1',
292
+ chartArea: {
293
+ left: 0,
294
+ top: '5%',
295
+ width: '100%',
296
+ height: '90%'
297
+ },
298
+ sliceVisibilityThreshold: 0.015
299
+ });
300
+ }
301
+ },
302
+
303
+ // Line Chart
304
+ dataLine: null,
305
+ viewLine: null,
306
+ drawLine: function () {
307
+ if (!self.dataLine) {
308
+ self.dataLine = new google.visualization.DataTable();
309
+ self.dataLine.addColumn('date', 'Date');
310
+ self.dataLine.addColumn('number', 'comment');
311
+ self.dataLine.addColumn('number', 'xmlrpc');
312
+ self.dataLine.addColumn('number', 'login');
313
+ self.dataLine.addColumn('number', 'admin');
314
+ self.dataLine.addColumn('number', 'public');
315
+ var i, j, k, m, n, cells, arr = [],
316
+ tr = $(ID('#', 'targets tr'));
317
+ for (m = tr.length, i = 0; i < m; i++) {
318
+ arr[i] = [];
319
+ cells = tr.eq(i).children();
320
+ for (n = cells.length, j = 0; j < n; j++) {
321
+ k = cells.eq(j).text();
322
+ arr[i].push(j ? Number(k) : new Date(k));
323
+ }
324
+ }
325
+ self.dataLine.addRows(arr);
326
+ }
327
+ if (!self.viewLine) {
328
+ self.viewLine = new google.visualization.LineChart(
329
+ document.getElementById(ID('chart-daily'))
330
+ );
331
+ }
332
+ var w = $(ID('#', 'chart-daily')).width();
333
+ if (w) {
334
+ w = w > 320 ? true : false;
335
+ self.viewLine.draw(self.dataLine, {
336
+ backgroundColor: '#f1f1f1',
337
+ legend: { position: 'bottom' },
338
+ hAxis: { format: 'MM/dd' },
339
+ vAxis: { textPosition: (w ? 'out' : 'in') },
340
+ chartArea: {
341
+ left: (w ? '10%' : 0),
342
+ top: '5%',
343
+ width: '100%',
344
+ height: '75%'
345
+ }
346
+ });
347
+ }
348
+ }
349
+ };
350
+
351
+ // google chart
352
+ function drawChart() {
353
+ if ($(ID('#', 'chart-countries')).length) {
354
+ chart.drawChart();
355
+ }
356
+ }
357
+
358
+ // Load / Save cookie using wpCookies in wp-includes/js/utils.js
359
+ function loadCookie(id) {
360
+ return ('undefined' !== typeof wpCookies && wpCookies.getHash(ID('$', id))) || {};
361
+ }
362
+
363
+ // setHash( name, value, expires, path, domain, secure )
364
+ function saveCookie(id, cookie) {
365
+ if ('undefined' !== typeof wpCookies) {
366
+ var path = 'undefined' !== typeof IP_GEO_BLOCK_AUTH ? IP_GEO_BLOCK_AUTH.home + IP_GEO_BLOCK_AUTH.admin : '';
367
+ wpCookies.setHash(ID('$', id), cookie, new Date(Date.now() + 2592000000), path);
368
+ }
369
+ }
370
+
371
+ // Click event handler to show/hide form-table
372
+ function toggleSection(title, id, cookie) {
373
+ var index = title.closest('fieldset').data('ip-geo-block');
374
+
375
+ // Show/Hide
376
+ title.parent().nextAll().toggle();
377
+ title.toggleClass(ID('dropup')).toggleClass(ID('dropdown'));
378
+
379
+ cookie[index] = title.hasClass(ID('dropdown')) ? 'o' : 'x';
380
+ saveCookie(id, cookie); // Save cookie
381
+
382
+ // redraw google chart
383
+ drawChart();
384
+ }
385
+
386
+ // form for export / import
387
+ function add_hidden_form(cmd) {
388
+ $('body').append(
389
+ '<div style="display:none">' +
390
+ '<form method="POST" id="' + ID('export-form') + '" action="' + IP_GEO_BLOCK.url.replace('ajax.php', 'post.php') + '">' +
391
+ '<input type="hidden" name="action" value="' + IP_GEO_BLOCK.action + '" />' +
392
+ '<input type="hidden" name="nonce" value="' + IP_GEO_BLOCK.nonce + '" />' +
393
+ '<input type="hidden" name="cmd" value="' + cmd + '" />' +
394
+ '<input type="hidden" name="data" value="" id="' + ID('export-data') + '"/>' +
395
+ '<input type="submit" value="submit" />' +
396
+ '</form>' +
397
+ '<input type="file" name="settings" id="' + ID('file-dialog') + '" />' +
398
+ '</div>'
399
+ );
400
+ }
401
+
402
+ $(function () {
403
+ // Make form style with fieldset and legend
404
+ var fieldset = $('<fieldset class="' + ID('field') + '"></fieldset>'),
405
+ legend = $('<legend></legend>'),
406
+
407
+ // Get tab number and cookie
408
+ tabNo = Number(IP_GEO_BLOCK.tab) || 0,
409
+ cookie = loadCookie(tabNo);
410
+
411
+ $('.form-table').each(function (index) {
412
+ var $this = $(this),
413
+ title = $this.prevAll('h2,h3:first'),
414
+ notes = title.nextUntil($this);
415
+
416
+ // Move title into the fieldset and wrap with legend
417
+ $this.wrap(fieldset).parent() // fieldset itself
418
+ .attr('id', ID('settings-' + index))
419
+ .data('ip-geo-block', index)
420
+ .prepend(title.wrap(legend).parent());
421
+ notes.insertBefore($this);
422
+
423
+ // Initialize show/hide form-table on tab 0, 1
424
+ if (tabNo <= 1) {
425
+ if ('undefined' === typeof cookie[index] || 'o' === cookie[index]) { // 'undefined', 'x' or 'o'
426
+ title.addClass(ID('dropdown')).parent().nextAll().show();
427
+ } else {
428
+ title.addClass(ID('dropup')).parent().nextAll().hide();
429
+ }
430
+ }
431
+ });
432
+
433
+ // Click event handler to show/hide form-table
434
+ if (tabNo <= 1) {
435
+ $('form').on('click', 'h2,h3', function (event) {
436
+ toggleSection($(this), tabNo, cookie);
437
+ return false;
438
+ });
439
+
440
+ // Toggle all
441
+ $(ID('#', 'toggle-sections')).on('click', function (event) {
442
+ var $this, n = 0,
443
+ id = [ID('dropdown'), ID('dropup')],
444
+ title = $(ID('.', 'field')).find('h2,h3');
445
+
446
+ title.each(function (i) {
447
+ n += $(this).hasClass(id[0]);
448
+ });
449
+
450
+ // update cookie
451
+ title.each(function (i) {
452
+ $this = $(this);
453
+ $this.parent().nextAll().toggle(n ? false : true);
454
+ $this.removeClass(id.join(' '))
455
+ .addClass(n ? id[1] : id[0]);
456
+ cookie[i] = n ? 'x' : 'o';
457
+ });
458
+
459
+ // Save cookie
460
+ saveCookie(tabNo, cookie);
461
+
462
+ // redraw google chart
463
+ drawChart();
464
+
465
+ return false;
466
+ });
467
+ }
468
+
469
+ // Inhibit to submit by return key
470
+ $(ID('#', 'inhibit')).on('submit', function () {
471
+ return false;
472
+ });
473
+
474
+ // Register event handler at specific tab
475
+ switch (tabNo) {
476
+ /*----------------------------------------
477
+ * Settings
478
+ *----------------------------------------*/
479
+ case 0:
480
+ // Scan your country code
481
+ $(ID('#', 'scan-code')).on('click', function (event) {
482
+ var parent = $(this).parent();
483
+ ajax_post('scanning', {
484
+ cmd: 'scan-code'
485
+ }, function (data) {
486
+ if (!parent.children('ul').length) {
487
+ parent.append('<ul id="' + ID('code-list') + '"></ul>');
488
+ }
489
+ parent = parent.children('ul').empty();
490
+
491
+ var key, val;
492
+ for (key in data) {
493
+ if (data.hasOwnProperty(key)) {
494
+ key = sanitize(key);
495
+ if ('string' === typeof data[key]) {
496
+ val = sanitize(data[key]);
497
+ } else {
498
+ val = sanitize(data[key].code);
499
+ key = '<abbr title="' + sanitize(data[key].type) + '">' + key + '</abbr>';
500
+ }
501
+ parent.append('<li>' + key + ' : <span class="' + ID('notice') + '">' + val + '</span></li>');
502
+ }
503
+ }
504
+ parent.show('slow');
505
+ });
506
+
507
+ return false;
508
+ });
509
+
510
+ // Matching rule
511
+ $(ID('@', 'matching_rule')).on('change', function () {
512
+ $(ID('@', 'white_list')).closest('tr').toggle(this.value === '0');
513
+ $(ID('@', 'black_list')).closest('tr').toggle(this.value === '1');
514
+ return false;
515
+ }).trigger('change');
516
+
517
+ $(ID('@', 'public_matching_rule')).on('change', function () {
518
+ $(ID('@', 'public_white_list')).closest('tr').toggle(this.value === '0');
519
+ $(ID('@', 'public_black_list')).closest('tr').toggle(this.value === '1');
520
+ return false;
521
+ }).trigger('change');
522
+
523
+ // Update local database
524
+ $(ID('@', 'update')).on('click', function (event) {
525
+ ajax_post('download', {
526
+ cmd: 'download'
527
+ }, function (res) {
528
+ var api, key, data;
529
+ for (api in res) {
530
+ if (res.hasOwnProperty(api)) {
531
+ data = res[api];
532
+ for (key in data) { // key: ipv4, ipv6
533
+ if (data.hasOwnProperty(key)) {
534
+ key = sanitize(key);
535
+ if (data[key].filename) {
536
+ $(ID('@', api + '_' + key + '_path')).val(sanitize(data[key].filename));
537
+ }
538
+ if (data[key].message) {
539
+ $(ID('#', api + '-' + key)).text(sanitize(data[key].message));
540
+ }
541
+ }
542
+ }
543
+ }
544
+ }
545
+ });
546
+
547
+ return false;
548
+ });
549
+
550
+ // Name of base class
551
+ var name = ID('%', 'settings');
552
+
553
+ // Show/Hide folding list at Login form
554
+ $(ID('@', 'validation_login')).on('change', function (event) {
555
+ var $this = $(this);
556
+ show_folding_list($this, $this, name, true);
557
+ return false;
558
+ }).trigger('change');
559
+
560
+ // Show/Hide description
561
+ $('select[name^="' + name + '"]').on('change', function (event) {
562
+ var $this = $(this);
563
+ show_description($this);
564
+ show_folding_list($this, $this, name, true);
565
+ return false;
566
+ }).trigger('change');
567
+
568
+ // Enable / Disable for Public facing pages
569
+ $(ID('@', 'validation_public')).on('change', function (event) {
570
+ set_front_end($(this));
571
+ return false;
572
+ }).trigger('change');
573
+
574
+ // Export / Import settings
575
+ add_hidden_form('validate');
576
+
577
+ // Export settings
578
+ $(ID('#', 'export')).on('click', function (event) {
579
+ if ('undefined' === typeof JSON) {
580
+ notice_html5();
581
+ return false;
582
+ }
583
+
584
+ var id = name, json = {};
585
+ $.each($(this).closest('form').serializeArray(), function (i, obj) {
586
+ if (-1 !== obj.name.indexOf(id)) {
587
+ json[obj.name] = obj.value;
588
+ }
589
+ });
590
+
591
+ json[id += '[signature]'] = encode_str(json[id]);
592
+ $(ID('#', 'export-data')).val(JSON.stringify(json));
593
+ $(ID('#', 'export-form')).trigger('submit');
594
+
595
+ return false;
596
+ });
597
+
598
+ // Import settings
599
+ $(ID('#', 'file-dialog')).on('change', function (event) {
600
+ if ('undefined' === typeof FileReader) {
601
+ notice_html5();
602
+ return false;
603
+ }
604
+
605
+ var id, file = event.target.files[0];
606
+ if (file) {
607
+ readfile(file, function (data) {
608
+ data = JSON.parse(data);
609
+ id = name + '[signature]';
610
+ if ('undefined' !== typeof data[id]) {
611
+ data[id] = encode_str(data[id]);
612
+ }
613
+ ajax_post('export-import', {
614
+ cmd: 'validate',
615
+ data: JSON.stringify(data)
616
+ }, deserialize_json);
617
+ });
618
+ }
619
+
620
+ return false;
621
+ });
622
+
623
+ $(ID('#', 'import')).on('click', function (event) {
624
+ $(ID('#', 'file-dialog')).trigger('click');
625
+ return false;
626
+ });
627
+
628
+ // Import pre-defined settings
629
+ $(ID('#', 'default')).on('click', function (event) {
630
+ confirm(IP_GEO_BLOCK.msg[0], function () {
631
+ ajax_post('pre-defined', {
632
+ cmd: 'import-default'
633
+ }, deserialize_json);
634
+ /*}, function (json) {
635
+ deserialize_json(json);
636
+ $('#submit').trigger('click');
637
+ });*/
638
+ });
639
+ return false;
640
+ });
641
+
642
+ $(ID('#', 'preferred')).on('click', function (event) {
643
+ confirm(IP_GEO_BLOCK.msg[0], function () {
644
+ ajax_post('pre-defined', {
645
+ cmd: 'import-preferred'
646
+ }, deserialize_json);
647
+ });
648
+ return false;
649
+ });
650
+
651
+ // Manipulate DB table for validation logs
652
+ $(ID('@', 'create_table')).on('click', function (event) {
653
+ confirm(IP_GEO_BLOCK.msg[1], function () {
654
+ ajax_table('create-table');
655
+ });
656
+ return false;
657
+ });
658
+
659
+ $(ID('@', 'delete_table')).on('click', function (event) {
660
+ confirm(IP_GEO_BLOCK.msg[2], function () {
661
+ ajax_table('delete-table');
662
+ });
663
+ return false;
664
+ });
665
+
666
+ // Folding list
667
+ $('ul.' + name + '_folding dfn').on('click', function (event) {
668
+ var $this = $(this).parent();
669
+ $this.children('li').toggle();
670
+ $this.toggleClass(ID('dropup')).toggleClass(ID('dropdown'));
671
+ return false;
672
+ });
673
+
674
+ // Decode
675
+ $(ID('#', 'decode')).on('click', function (event) {
676
+ var elm = $(ID('@', 'signature')),
677
+ str = elm.val();
678
+ if (str.search(/,/) === -1) {
679
+ elm.val(decode_str(str));
680
+ } else {
681
+ elm.val(encode_str(str));
682
+ }
683
+ return false;
684
+ });
685
+
686
+ // Response message and Redirect URL
687
+ $(ID('@', 'response_code')).on('change', function (event) {
688
+ var res = parseInt($(this).val() / 100, 10),
689
+ elm = $(this).closest('tr').nextAll('tr');
690
+ if (res <= 3) { // 2xx, 3xx
691
+ elm.each(function (index) {
692
+ if (0 === index) { $(this).show(); } // redirect_uri
693
+ else if (1 === index) { $(this).hide(); } // response_msg
694
+ });
695
+ }
696
+ else { // 4xx, 5xx
697
+ elm.each(function (index) {
698
+ if (0 === index) { $(this).hide(); } // redirect_uri
699
+ else if (1 === index) { $(this).show(); } // response_msg
700
+ });
701
+ }
702
+ }).trigger('change');
703
+
704
+ // Show WordPress installation info
705
+ $(ID('#', 'show-info')).on('click', function (event) {
706
+ $(ID('#', 'wp-info')).empty();
707
+ ajax_post('wp-info', {
708
+ cmd: 'show-info'
709
+ }, function (data) {
710
+ var key, val, res = [];
711
+ for (key in data) {
712
+ if (data.hasOwnProperty(key)) {
713
+ for (val in data[key]) {
714
+ if (data[key].hasOwnProperty(val)) {
715
+ res.push('- ' + val + ' ' + data[key][val]);
716
+ }
717
+ }
718
+ }
719
+ }
720
+
721
+ // response should be escaped at server side
722
+ $(ID('#', 'wp-info')).html('<textarea rows="' + res.length + '">' + /*sanitize*/(res.join("\n")) + '</textarea>').find('textarea').select();
723
+ return false;
724
+ });
725
+ });
726
+
727
+ // Submit
728
+ $('#submit').on('click', function (event) {
729
+ var elm = $(ID('@', 'signature')),
730
+ str = elm.val();
731
+ if (str.search(/,/) !== -1) {
732
+ elm.val(encode_str(str));
733
+ }
734
+ return true;
735
+ });
736
+ break;
737
+
738
+ /*----------------------------------------
739
+ * Statistics
740
+ *----------------------------------------*/
741
+ case 1:
742
+ // https://developers.google.com/loader/#Dynamic
743
+ if ($(ID('#', 'chart-countries')).length && 'object' === typeof google) {
744
+ google.load('visualization', '1', {
745
+ packages: ['corechart'],
746
+ callback: function () {
747
+ chart.drawChart();
748
+ }
749
+ });
750
+ }
751
+
752
+ // Statistics
753
+ $(ID('@', 'clear_statistics')).on('click', function (event) {
754
+ confirm(IP_GEO_BLOCK.msg[3], function () {
755
+ ajax_clear('statistics', null);
756
+ });
757
+ return false;
758
+ });
759
+
760
+ // Statistics
761
+ $(ID('@', 'clear_cache')).on('click', function (event) {
762
+ confirm(IP_GEO_BLOCK.msg[4], function () {
763
+ ajax_clear('cache', null);
764
+ });
765
+ return false;
766
+ });
767
+ break;
768
+
769
+ /*----------------------------------------
770
+ * Search
771
+ *----------------------------------------*/
772
+ case 2:
773
+ // Google Maps API error
774
+ $(window).on(ID('gmap-error'), function () {
775
+ ajax_post(null, { cmd: 'gmap-error' }, function (data) {
776
+ redirect(data.page, data.tab);
777
+ });
778
+ });
779
+
780
+ // Initialize map if exists
781
+ var map = $(ID('#', 'map'));
782
+ if ('object' === typeof google) {
783
+ // Initialize map if exists
784
+ map.each(function () {
785
+ $(this).GmapRS();
786
+ });
787
+ } else {
788
+ map.each(function () {
789
+ $(this).empty().html(
790
+ '<iframe src="//maps.google.com/maps?output=embed" frameborder="0" style="width:100%; height:400px; border:0" allowfullscreen></iframe>'
791
+ );
792
+ });
793
+ }
794
+
795
+ // Search Geolocation
796
+ $(ID('@', 'get_location')).on('click', function (event) {
797
+ var whois = $(ID('#', 'whois')),
798
+ ip = $(ID('@', 'ip_address')).val();
799
+
800
+ if (ip) {
801
+ whois.hide().empty();
802
+
803
+ // Get whois data
804
+ var obj = $.whois(ip, function (data) {
805
+ var i, str = '';
806
+ for (i = 0; i < data.length; i++) {
807
+ str +=
808
+ '<tr>' +
809
+ '<td>' + data[i].name + '</td>' +
810
+ '<td>' + data[i].value + '</td>' +
811
+ '</tr>';
812
+ }
813
+
814
+ whois.html(
815
+ '<fieldset class="' + ID('field') + '">' +
816
+ '<legend><h2 id="' + ID('whois-title') + '" class="' + ID('dropdown') + '">Whois</h2></legend>' +
817
+ '<table class="' + ID('table') + '">' + str + '</table>' +
818
+ '<fieldset>'
819
+ ).fadeIn('slow');
820
+
821
+ $(ID('#', 'whois-title')).on('click', function (event) {
822
+ var $this = $(this);
823
+ $this.parent().nextAll().toggle();
824
+ $this.toggleClass(ID('dropup')).toggleClass(ID('dropdown'));
825
+ return false;
826
+ });
827
+ });
828
+
829
+ // Show map
830
+ ajax_post('loading', {
831
+ cmd: 'search',
832
+ ip: ip,
833
+ which: $(ID('@', 'service')).val()
834
+ }, function (data) {
835
+ var key, info = '',
836
+ latitude = sanitize(data.latitude || '0'),
837
+ longitude = sanitize(data.longitude || '0'),
838
+ zoom = (data.latitude || data.longitude) ? 8 : 2;
839
+
840
+ for (key in data) {
841
+ if (data.hasOwnProperty(key)) {
842
+ key = sanitize(key);
843
+ info +=
844
+ '<li>' +
845
+ '<span class="' + ID('title' ) + '">' + key + ' : </span>' +
846
+ '<span class="' + ID('result') + '">' + sanitize(data[key]) + '</span>' +
847
+ '</li>';
848
+ }
849
+ }
850
+
851
+ if ('object' === typeof google) {
852
+ map.GmapRS('addMarker', {
853
+ latitude: latitude,
854
+ longitude: longitude,
855
+ title: ip,
856
+ content: '<ul>' + info + '</ul>',
857
+ show: true,
858
+ zoom: zoom
859
+ });
860
+ } else {
861
+ map.css({
862
+ height: '600px',
863
+ backgroundColor: 'transparent'
864
+ }).empty().html(
865
+ '<ul style="margin-top:0; margin-left:1em;">' +
866
+ '<li>' +
867
+ '<span class="' + ID('title' ) + '">' + 'IP address' + ' : </span>' +
868
+ '<span class="' + ID('result') + '">' + sanitize(ip) + '</span>' +
869
+ '</li>' +
870
+ info +
871
+ /*'<li>' +
872
+ '<span class="' + ID('title' ) + '">' + 'show map' + ' : </span>' +
873
+ '<span class="' + ID('result') + '">' + '<a href="//maps.google.com/maps?q=' + latitude + ',' + longitude + '">Click here</a>' + '</span>' +
874
+ '</li>' +*/
875
+ '</ul>'
876
+ + '<iframe src="//maps.google.com/maps?q=' + latitude + ',' + longitude + '&z=' + zoom + '&output=embed" frameborder="0" style="width:100%; height:400px; border:0" allowfullscreen></iframe>'
877
+ /*+ '<iframe src="//www.google.com/maps/embed/v1/place?key=...&q=%20&center=' + latitude + ',' + longitude + '&zoom=' + zoom + '" frameborder="0" style="width:100%; height:400px; border:0" allowfullscreen></iframe>'*/
878
+ );
879
+ }
880
+ }, [obj]);
881
+ }
882
+
883
+ return false;
884
+ });
885
+
886
+ // Preset IP address
887
+ if ($(ID('@', 'ip_address')).val()) {
888
+ $(ID('@', 'get_location')).trigger('click');
889
+ }
890
+ break;
891
+
892
+ /*----------------------------------------
893
+ * Logs
894
+ *----------------------------------------*/
895
+ case 4:
896
+ // Kick-off footable
897
+ if ($(ID('.', 'log')).hide().length) {
898
+ ajax_post('logs', {
899
+ cmd: 'restore',
900
+ which: null,
901
+ time: new Date() - ip_geo_block_time
902
+ }, function (data) {
903
+ var key;
904
+ for (key in data) {
905
+ if (data.hasOwnProperty(key)) {
906
+ key = sanitize(key); // data has been already sanitized
907
+ // $(ID('#', 'log-' + key)).html($.parseHTML(data[key])); // jQuery 1.8+
908
+ $(ID('#', 'log-' + key)).html(data[key]);
909
+ }
910
+ }
911
+
912
+ if (typeof $.fn.footable === 'function') {
913
+ $(ID('.', 'log')).fadeIn('slow').footable();
914
+ }
915
+
916
+ // Jump to search tab with opening new window
917
+ $('tbody[id^="' + ID('$', 'log-') + '"]').on('click', 'a', function (event) {
918
+ window.open(window.location.href.replace(/tab=\d/, 'tab=2') + '&ip=' + $(this).text().replace(/[^\w\.\:\*]/, ''));
919
+ return false;
920
+ });
921
+ });
922
+ }
923
+
924
+ // Clear filter logs
925
+ $(ID('#', 'reset-filter')).on('click', function (event) {
926
+ $('.footable').trigger('footable_clear_filter');
927
+ return false;
928
+ });
929
+
930
+ // Validation logs
931
+ $(ID('@', 'clear_logs')).on('click', function (event) {
932
+ confirm(IP_GEO_BLOCK.msg[5], function () {
933
+ ajax_clear('logs', null);
934
+ });
935
+ return false;
936
+ });
937
+
938
+ // Export / Import settings
939
+ add_hidden_form('export-logs');
940
+
941
+ // Export logs
942
+ $(ID('#', 'export-logs')).on('click', function (event) {
943
+ $(ID('#', 'export-form')).trigger('submit');
944
+ return false;
945
+ });
946
+ break;
947
+ }
948
+ });
949
+ }(jQuery, window, document));
admin/js/admin.min.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ /*
2
+ Project: WordPress IP Geo Block
3
+ Copyright (c) 2015-2016 tokkonopapa (tokkonopapa@yahoo.com)
4
+ This software is released under the MIT License.
5
+ */
6
+ var ip_geo_block_time=new Date;(function(a,l,C){function b(a,b){var c={".":".ip-geo-block-","#":"#ip-geo-block-","@":"#ip_geo_block_settings_",$:"ip-geo-block-","%":"ip_geo_block_"};return"undefined"!==typeof b?c[a]+b:c.$+a}function h(a){return a?a.toString().replace(/[&<>"']/g,function(a){return{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[a]}):""}function x(c,f){f?a(b("#",c)).addClass(b("loading")):a(b("#",c)).removeClass(b("loading"))}function q(a,b){l.confirm(h(a))&&b()}function v(a,b){l.alert(a?h(a+": "+b):h(b))}function y(a,b){if(-1!==location.href.indexOf(a)){var c=h(a)+(b?"&"+h(b):"");"undefined"===typeof IP_GEO_BLOCK_ZEP?l.location.href=c:IP_GEO_BLOCK_ZEP.redirect(c)}}function p(b,f,m,g){b&&x(b,!0);f.action=IP_GEO_BLOCK.action;f.nonce=IP_GEO_BLOCK.nonce;a.post(IP_GEO_BLOCK.url,f).done(function(a,b,d){m(a)}).fail(function(a,b,d){v(b,a.responseText)}).always(function(){b&&(g?a.when.apply(a,g).then(function(){x(b,!1)}):x(b,!1))})}function z(a,b){p(a,{cmd:"clear-"+a,which:b},function(a){y(a.page,a.tab)})}function D(a){p(a,{cmd:a},function(a){y(a.page,a.tab)})}function A(c,f,m,g){var k=!1,k=k|(0===c.prop("type").indexOf("checkbox")&&c.is(":checked")),k=k|(0===c.prop("type").indexOf("select")&&"0"!==c.val());f.nextAll("."+m+"_folding").each(function(c,d){d=a(d);k&&g?d.removeClass("folding-disable"):(d.children("li").hide(),d.addClass("folding-disable"),d.removeClass(b("dropdown")).addClass(b("dropup")))})}function u(a){return String(a).replace(/[a-z]/gi,function(a){return String.fromCharCode(a.charCodeAt(0)+("n">a.toLowerCase()?13:-13))})}function J(a,b){var c=new FileReader;c.onload=function(a){b&&b(a.target.result)};c.onerror=function(a){v("Error",a.target.error.code)};c.readAsText(a)}function E(c){var f=b("%","settings"),m=c.is(":checked"),g=a(b("@","public_target_rule")),k=c.closest("tr").nextAll("tr");k.find('[name^="'+f+'"]').prop("disabled",!m);k.find(b(".","desc")).css("opacity",m?1:.5);A(c,g,f,"1"===g.val()?!0:!1)}function B(c){if(c){"string"===typeof c&&(c=JSON.parse(c));a(b("#","import")).closest("form").deserialize(c);a.each(["matching_rule","validation_login","validation_plugins","validation_themes"],function(c,g){a(b("@",g)).trigger("change")});E(a(b("@","validation_public")));var f=b("%","settings[providers][IPInfoDB]");a(b("@","providers_IPInfoDB")).prop("checked",c[f]?!0:!1)}}function F(){a(b("#","chart-countries")).length&&G.drawChart()}function H(a,f){if("undefined"!==typeof wpCookies){var c="undefined"!==typeof IP_GEO_BLOCK_AUTH?IP_GEO_BLOCK_AUTH.home+IP_GEO_BLOCK_AUTH.admin:"";wpCookies.setHash(b("$",a),f,new Date(Date.now()+2592E6),c)}}function I(c){a("body").append('<div style="display:none"><form method="POST" id="'+b("export-form")+'" action="'+IP_GEO_BLOCK.url.replace("ajax.php","post.php")+'"><input type="hidden" name="action" value="'+IP_GEO_BLOCK.action+'" /><input type="hidden" name="nonce" value="'+IP_GEO_BLOCK.nonce+'" /><input type="hidden" name="cmd" value="'+c+'" /><input type="hidden" name="data" value="" id="'+b("export-data")+'"/><input type="submit" value="submit" /></form><input type="file" name="settings" id="'+b("file-dialog")+'" /></div>')}a.fn.deserialize=function(b,f){return this.each(function(){var c,g,f,h=this,d={};for(c in b)b.hasOwnProperty(c)&&(g=decodeURIComponent(c),f=decodeURIComponent(b[c]),g in d||(d[g]=[]),d[g].push(f));a.each(d,function(b,d){a('[name="'+b+'"]:input',h).val(d)})})};var G={self:this,drawChart:function(){this.drawPie();this.drawLine()},dataPie:null,viewPie:null,drawPie:function(){if(!self.dataPie){self.dataPie=new google.visualization.DataTable;self.dataPie.addColumn("string","Country");self.dataPie.addColumn("number","Requests");var c;a(b("#","countries li")).each(function(){c=a(this).text().split(":");self.dataPie.addRow([c[0]||"",Number(c[1])])})}self.viewPie||(self.viewPie=new google.visualization.PieChart(C.getElementById(b("chart-countries"))));a(b("#","chart-countries")).width()&&self.viewPie.draw(self.dataPie,{backgroundColor:"#f1f1f1",chartArea:{left:0,top:"5%",width:"100%",height:"90%"},sliceVisibilityThreshold:.015})},dataLine:null,viewLine:null,drawLine:function(){if(!self.dataLine){self.dataLine=new google.visualization.DataTable;self.dataLine.addColumn("date","Date");self.dataLine.addColumn("number","comment");self.dataLine.addColumn("number","xmlrpc");self.dataLine.addColumn("number","login");self.dataLine.addColumn("number","admin");self.dataLine.addColumn("number","public");var c,f,h,g,k,l,d=[],e=a(b("#","targets tr"));g=e.length;for(c=0;c<g;c++)for(d[c]=[],l=e.eq(c).children(),k=l.length,f=0;f<k;f++)h=l.eq(f).text(),d[c].push(f?Number(h):new Date(h));self.dataLine.addRows(d)}self.viewLine||(self.viewLine=new google.visualization.LineChart(C.getElementById(b("chart-daily"))));if(c=a(b("#","chart-daily")).width())c=320<c?!0:!1,self.viewLine.draw(self.dataLine,{backgroundColor:"#f1f1f1",legend:{position:"bottom"},hAxis:{format:"MM/dd"},vAxis:{textPosition:c?"out":"in"},chartArea:{left:c?"10%":0,top:"5%",width:"100%",height:"75%"}})}};a(function(){var c=a('<fieldset class="'+b("field")+'"></fieldset>'),f=a("<legend></legend>"),m=Number(IP_GEO_BLOCK.tab)||0,g="undefined"!==typeof wpCookies&&wpCookies.getHash(b("$",m))||{};a(".form-table").each(function(d){var e=a(this),n=e.prevAll("h2,h3:first"),t=n.nextUntil(e);e.wrap(c).parent().attr("id",b("settings-"+d)).data("ip-geo-block",d).prepend(n.wrap(f).parent());t.insertBefore(e);1>=m&&("undefined"===typeof g[d]||"o"===g[d]?n.addClass(b("dropdown")).parent().nextAll().show():n.addClass(b("dropup")).parent().nextAll().hide())});1>=m&&(a("form").on("click","h2,h3",function(d){d=a(this);var e=d.closest("fieldset").data("ip-geo-block");d.parent().nextAll().toggle();d.toggleClass(b("dropup")).toggleClass(b("dropdown"));g[e]=d.hasClass(b("dropdown"))?"o":"x";H(m,g);F();return!1}),a(b("#","toggle-sections")).on("click",function(d){var e,c=0,t=[b("dropdown"),b("dropup")];d=a(b(".","field")).find("h2,h3");d.each(function(b){c+=a(this).hasClass(t[0])});d.each(function(b){e=a(this);e.parent().nextAll().toggle(c?!1:!0);e.removeClass(t.join(" ")).addClass(c?t[1]:t[0]);g[b]=c?"x":"o"});H(m,g);F();return!1}));a(b("#","inhibit")).on("submit",function(){return!1});switch(m){case 0:a(b("#","scan-code")).on("click",function(d){var c=a(this).parent();p("scanning",{cmd:"scan-code"},function(a){c.children("ul").length||c.append('<ul id="'+b("code-list")+'"></ul>');c=c.children("ul").empty();var d,e;for(d in a)a.hasOwnProperty(d)&&(d=h(d),"string"===typeof a[d]?e=h(a[d]):(e=h(a[d].code),d='<abbr title="'+h(a[d].type)+'">'+d+"</abbr>"),c.append("<li>"+d+' : <span class="'+b("notice")+'">'+e+"</span></li>"));c.show("slow")});return!1});a(b("@","matching_rule")).on("change",function(){a(b("@","white_list")).closest("tr").toggle("0"===this.value);a(b("@","black_list")).closest("tr").toggle("1"===this.value);return!1}).trigger("change");a(b("@","public_matching_rule")).on("change",function(){a(b("@","public_white_list")).closest("tr").toggle("0"===this.value);a(b("@","public_black_list")).closest("tr").toggle("1"===this.value);return!1}).trigger("change");a(b("@","update")).on("click",function(d){p("download",{cmd:"download"},function(d){var c,e,r;for(c in d)if(d.hasOwnProperty(c))for(e in r=d[c],r)r.hasOwnProperty(e)&&(e=h(e),r[e].filename&&a(b("@",c+"_"+e+"_path")).val(h(r[e].filename)),r[e].message&&a(b("#",c+"-"+e)).text(h(r[e].message)))});return!1});var k=b("%","settings");a(b("@","validation_login")).on("change",function(b){b=a(this);A(b,b,k,!0);return!1}).trigger("change");a('select[name^="'+k+'"]').on("change",function(d){d=a(this);var c,n=b(".","desc");d.next(n).empty();(c=d.children("option:selected").data("desc"))&&d.next(n).html(a.parseHTML(c));A(d,d,k,!0);return!1}).trigger("change");a(b("@","validation_public")).on("change",function(b){E(a(this));return!1}).trigger("change");I("validate");a(b("#","export")).on("click",function(d){if("undefined"===typeof JSON)return v(null,IP_GEO_BLOCK.msg[6]),!1;var c=k,n={};a.each(a(this).closest("form").serializeArray(),function(a,b){-1!==b.name.indexOf(c)&&(n[b.name]=b.value)});n[c+="[signature]"]=l.btoa(u(n[c]));a(b("#","export-data")).val(JSON.stringify(n));a(b("#","export-form")).trigger("submit");return!1});a(b("#","file-dialog")).on("change",function(a){if("undefined"===typeof FileReader)return v(null,IP_GEO_BLOCK.msg[6]),!1;var b;(a=a.target.files[0])&&J(a,function(a){a=JSON.parse(a);b=k+"[signature]";"undefined"!==typeof a[b]&&(a[b]=l.btoa(u(a[b])));p("export-import",{cmd:"validate",data:JSON.stringify(a)},B)});return!1});a(b("#","import")).on("click",function(d){a(b("#","file-dialog")).trigger("click");return!1});a(b("#","default")).on("click",function(a){q(IP_GEO_BLOCK.msg[0],function(){p("pre-defined",{cmd:"import-default"},B)});return!1});a(b("#","preferred")).on("click",function(a){q(IP_GEO_BLOCK.msg[0],function(){p("pre-defined",{cmd:"import-preferred"},B)});return!1});a(b("@","create_table")).on("click",function(a){q(IP_GEO_BLOCK.msg[1],function(){D("create-table")});return!1});a(b("@","delete_table")).on("click",function(a){q(IP_GEO_BLOCK.msg[2],function(){D("delete-table")});return!1});a("ul."+k+"_folding dfn").on("click",function(d){d=a(this).parent();d.children("li").toggle();d.toggleClass(b("dropup")).toggleClass(b("dropdown"));return!1});a(b("#","decode")).on("click",function(d){d=a(b("@","signature"));var c=d.val();-1===c.search(/,/)?d.val(u(l.atob(c))):d.val(l.btoa(u(c)));return!1});a(b("@","response_code")).on("change",function(b){b=parseInt(a(this).val()/100,10);var d=a(this).closest("tr").nextAll("tr");3>=b?d.each(function(b){0===b?a(this).show():1===b&&a(this).hide()}):d.each(function(b){0===b?a(this).hide():1===b&&a(this).show()})}).trigger("change");a(b("#","show-info")).on("click",function(d){a(b("#","wp-info")).empty();p("wp-info",{cmd:"show-info"},function(d){var c,e,f=[];for(c in d)if(d.hasOwnProperty(c))for(e in d[c])d[c].hasOwnProperty(e)&&f.push("- "+e+" "+d[c][e]);a(b("#","wp-info")).html('<textarea rows="'+f.length+'">'+f.join("\n")+"</textarea>").find("textarea").select();return!1})});a("#submit").on("click",function(d){d=a(b("@","signature"));var c=d.val();-1!==c.search(/,/)&&d.val(l.btoa(u(c)));return!0});break;case 1:a(b("#","chart-countries")).length&&"object"===typeof google&&google.load("visualization","1",{packages:["corechart"],callback:function(){G.drawChart()}});a(b("@","clear_statistics")).on("click",function(a){q(IP_GEO_BLOCK.msg[3],function(){z("statistics",null)});return!1});a(b("@","clear_cache")).on("click",function(a){q(IP_GEO_BLOCK.msg[4],function(){z("cache",null)});return!1});break;case 2:a(l).on(b("gmap-error"),function(){p(null,{cmd:"gmap-error"},function(a){y(a.page,a.tab)})});var w=a(b("#","map"));"object"===typeof google?w.each(function(){a(this).GmapRS()}):w.each(function(){a(this).empty().html('<iframe src="//maps.google.com/maps?output=embed" frameborder="0" style="width:100%; height:400px; border:0" allowfullscreen></iframe>')});a(b("@","get_location")).on("click",function(c){var d=a(b("#","whois")),f=a(b("@","ip_address")).val();f&&(d.hide().empty(),c=a.whois(f,function(c){var e,f="";for(e=0;e<c.length;e++)f+="<tr><td>"+c[e].name+"</td><td>"+c[e].value+"</td></tr>";d.html('<fieldset class="'+b("field")+'"><legend><h2 id="'+b("whois-title")+'" class="'+b("dropdown")+'">Whois</h2></legend><table class="'+b("table")+'">'+f+"</table><fieldset>").fadeIn("slow");a(b("#","whois-title")).on("click",function(c){c=a(this);c.parent().nextAll().toggle();c.toggleClass(b("dropup")).toggleClass(b("dropdown"));return!1})}),p("loading",{cmd:"search",ip:f,which:a(b("@","service")).val()},function(a){var c,d="",e=h(a.latitude||"0"),g=h(a.longitude||"0"),k=a.latitude||a.longitude?8:2;for(c in a)a.hasOwnProperty(c)&&(c=h(c),d+='<li><span class="'+b("title")+'">'+c+' : </span><span class="'+b("result")+'">'+h(a[c])+"</span></li>");"object"===typeof google?w.GmapRS("addMarker",{latitude:e,longitude:g,title:f,content:"<ul>"+d+"</ul>",show:!0,zoom:k}):w.css({height:"600px",backgroundColor:"transparent"}).empty().html('<ul style="margin-top:0; margin-left:1em;"><li><span class="'+b("title")+'">IP address : </span><span class="'+b("result")+'">'+h(f)+"</span></li>"+d+'</ul><iframe src="//maps.google.com/maps?q='+e+","+g+"&z="+k+'&output=embed" frameborder="0" style="width:100%; height:400px; border:0" allowfullscreen></iframe>')},[c]));return!1});a(b("@","ip_address")).val()&&a(b("@","get_location")).trigger("click");break;case 4:a(b(".","log")).hide().length&&p("logs",{cmd:"restore",which:null,time:new Date-ip_geo_block_time},function(c){for(var d in c)c.hasOwnProperty(d)&&(d=h(d),a(b("#","log-"+d)).html(c[d]));"function"===typeof a.fn.footable&&a(b(".","log")).fadeIn("slow").footable();a('tbody[id^="'+b("$","log-")+'"]').on("click","a",function(b){l.open(l.location.href.replace(/tab=\d/,"tab=2")+"&ip="+a(this).text().replace(/[^\w\.\:\*]/,""));return!1})}),a(b("#","reset-filter")).on("click",function(b){a(".footable").trigger("footable_clear_filter");return!1}),a(b("@","clear_logs")).on("click",function(a){q(IP_GEO_BLOCK.msg[5],function(){z("logs",null)});return!1}),I("export-logs"),a(b("#","export-logs")).on("click",function(c){a(b("#","export-form")).trigger("submit");return!1})}})})(jQuery,window,document);
admin/js/authenticate.js ADDED
@@ -0,0 +1,396 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*jslint white: true */
2
+ /*!
3
+ * Project: WP-ZEP - Zero-day exploit Prevention for wp-admin
4
+ * Copyright (c) 2015-2016 tokkonopapa (tokkonopapa@yahoo.com)
5
+ * This software is released under the MIT License.
6
+ */
7
+ // utility object
8
+ var IP_GEO_BLOCK_ZEP = {
9
+ init: false,
10
+ auth: 'ip-geo-block-auth-nonce',
11
+ nonce: IP_GEO_BLOCK_AUTH.nonce || '',
12
+ redirect: function (url) {
13
+ 'use strict';
14
+ if (-1 !== location.href.indexOf(url)) {
15
+ if (this.nonce) {
16
+ url += (url.indexOf('?') >= 0 ? '&' : '?') + this.auth + '=' + this.nonce;
17
+ }
18
+ window.location.href = url;
19
+ }
20
+ }
21
+ };
22
+
23
+ (function ($, document) {
24
+ 'use strict';
25
+
26
+ // produce safe text for HTML
27
+ function sanitize(str) {
28
+ return str ? str.toString().replace(/[&<>"']/g, function (match) {
29
+ return {
30
+ '&': '&amp;',
31
+ '<': '&lt;',
32
+ '>': '&gt;',
33
+ '"': '&quot;',
34
+ "'": '&#39;'
35
+ }[match];
36
+ }) : '';
37
+ }
38
+
39
+ // Parse a URL and return its components
40
+ function parse_uri(uri) {
41
+ // avoid malformed URI error when uri includes '%'
42
+ uri = /*decodeURIComponent*/(uri ? uri.toString() : '');
43
+
44
+ var m = uri.match(
45
+ // https://tools.ietf.org/html/rfc3986#appendix-B
46
+ /^(?:([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/
47
+ );
48
+
49
+ // scheme :// authority path ? query # fragment
50
+ return {
51
+ scheme: m[1] || '',
52
+ relative: m[2] || '',
53
+ authority: m[3] || '',
54
+ path: m[4] || '',
55
+ query: m[5] || '',
56
+ fragment: m[6] || ''
57
+ };
58
+ }
59
+
60
+ // Compose a URL from components
61
+ function compose_uri(uri) {
62
+ return (uri.scheme ? uri.scheme + ':' : '') +
63
+ (uri.relative + uri.path) +
64
+ (uri.query ? '?' + uri.query : '') +
65
+ (uri.fragment ? '#' + uri.fragment : '');
66
+ }
67
+
68
+ /**
69
+ * Returns canonicalized absolute pathname
70
+ *
71
+ * This code is based on http://phpjs.org/functions/realpath/
72
+ */
73
+ function realpath(uri) {
74
+ var i, path, real = [];
75
+
76
+ // extract pathname (avoid `undefined`)
77
+ if (typeof uri !== 'object') {
78
+ uri = parse_uri(uri);
79
+ }
80
+
81
+ // focusing only at pathname
82
+ path = uri.path;
83
+
84
+ // if it's not absolute, add root path
85
+ if ('/' !== path.charAt(0)) {
86
+ i = window.location.pathname;
87
+ path = i.substring(0, i.lastIndexOf('/') + 1) + path;
88
+ }
89
+
90
+ // explode the given path into it's parts
91
+ path = path.split('/');
92
+
93
+ // if path ends with `/`, adds it to the last part
94
+ if ('' === path[path.length - 1]) {
95
+ path.pop();
96
+ path[path.length - 1] += '/';
97
+ }
98
+
99
+ for (i in path) {
100
+ if (path.hasOwnProperty(i)) {
101
+ // this is'nt really interesting
102
+ if ('.' === path[i]) {
103
+ continue;
104
+ }
105
+
106
+ // this reduces the realpath
107
+ if ('..' === path[i]) {
108
+ if (real.length > 0) {
109
+ real.pop();
110
+ }
111
+ }
112
+
113
+ // this adds parts to the realpath
114
+ else {
115
+ if ((real.length < 1) || (path[i] !== '')) {
116
+ real.push(path[i]);
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ // returns the absloute path as a string
123
+ return real.join('/').replace(/\/\//g, '/');
124
+ }
125
+ /*
126
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
127
+ function encodeURIComponentRFC3986(str) {
128
+ return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
129
+ return '%' + c.charCodeAt(0).toString(16);
130
+ });
131
+ }
132
+ */
133
+ // append the nonce as query strings to the uri
134
+ function add_query_nonce(uri, nonce) {
135
+ if (typeof uri !== 'object') { // `string` or `undefined`
136
+ uri = parse_uri(uri || location.href);
137
+ }
138
+
139
+ var data = uri.query ? uri.query.split('&') : [],
140
+ i = data.length;
141
+
142
+ // remove an old nonce
143
+ while (i-- > 0) {
144
+ if (data[i].indexOf(IP_GEO_BLOCK_ZEP.auth) === 0) {
145
+ data.splice(i, 1);
146
+ break;
147
+ }
148
+ }
149
+
150
+ data.push(IP_GEO_BLOCK_ZEP.auth + '=' + encodeURIComponent(nonce));//RFC3986
151
+ uri.query = data.join('&');
152
+
153
+ return compose_uri(uri);
154
+ }
155
+
156
+ // regular expression to find target for is_admin()
157
+ var regexp = new RegExp(
158
+ '^(?:' + (IP_GEO_BLOCK_AUTH.home || '') + IP_GEO_BLOCK_AUTH.admin
159
+ + '|' + (IP_GEO_BLOCK_AUTH.home || '') + IP_GEO_BLOCK_AUTH.plugins
160
+ + '|' + (IP_GEO_BLOCK_AUTH.home || '') + IP_GEO_BLOCK_AUTH.themes
161
+ + ')(?:.*\.php|.*\/)?$'
162
+ );
163
+
164
+ // check the URI where the nonce is needed
165
+ function is_admin(uri) {
166
+ // parse uri and get real path
167
+ uri = parse_uri(uri ? uri.toString().toLowerCase() : location.pathname);
168
+
169
+ // get absolute path with flattening `./`, `../`, `//`
170
+ var path = realpath(uri);
171
+
172
+ // possibly scheme is `javascript` and path is `void(0);`
173
+ if (/https?/.test(uri.scheme) || !uri.scheme) {
174
+ // external domain (`http://example` or `www.example`)
175
+ if (uri.authority && uri.authority !== location.host.toLowerCase()) {
176
+ return -1; // external
177
+ }
178
+
179
+ // exclude the case which component is only fragment (`#...`)
180
+ if ((uri.scheme || uri.path || uri.query) && regexp.test(path)) {
181
+ return 1; // internal for admin
182
+ }
183
+ }
184
+
185
+ return 0; // internal not admin
186
+ }
187
+
188
+ // `theme-install.php` eats the query and set it to `request[browse]` as a parameter
189
+ var theme_featured = function (data) {
190
+ var i = data.length;
191
+ while (i-- > 0) {
192
+ if (data[i].indexOf('request%5Bbrowse%5D=ip-geo-block-auth') !== -1) {
193
+ data[i] = 'request%5Bbrowse%5D=featured'; // correct the parameter
194
+ break;
195
+ }
196
+ }
197
+ return data;
198
+ };
199
+
200
+ // `upload.php` eats the query and set it to `query[ip-geo-block-auth-nonce]` as a parameter
201
+ var media_library = function (data) {
202
+ var i = data.length;
203
+ while (i-- > 0) {
204
+ if (data[i].indexOf('query%5Bip-geo-block-auth-nonce%5D=') !== -1) {
205
+ delete data[i];
206
+ break;
207
+ }
208
+ }
209
+ return data;
210
+ };
211
+
212
+ // list of excluded links
213
+ var ajax_links = {
214
+ 'upload.php': media_library,
215
+ 'theme-install.php': theme_featured,
216
+ 'network/theme-install.php': theme_featured
217
+ };
218
+
219
+ // check excluded path
220
+ function check_ajax(path) {
221
+ path = path.replace(IP_GEO_BLOCK_AUTH.home + IP_GEO_BLOCK_AUTH.admin, '');
222
+ return ajax_links.hasOwnProperty(path) ? ajax_links[path] : null;
223
+ }
224
+
225
+ // embed a nonce before an Ajax request is sent
226
+ $(document).ajaxSend(function (event, jqxhr, settings) {
227
+ var nonce = IP_GEO_BLOCK_ZEP.nonce;
228
+ if (nonce && is_admin(settings.url) === 1) {
229
+ // multipart/form-data (XMLHttpRequest Level 2)
230
+ // IE10+, Firefox 4+, Safari 5+, Android 3+
231
+ if (typeof window.FormData !== 'undefined' && settings.data instanceof FormData) {
232
+ settings.data.append(IP_GEO_BLOCK_ZEP.auth, nonce);
233
+ }
234
+
235
+ // application/x-www-form-urlencoded
236
+ else {
237
+ // Behavior of jQuery Ajax
238
+ // method url url+data data
239
+ // GET query query data
240
+ // POST query query data
241
+ var uri = parse_uri(settings.url);
242
+
243
+ if (typeof settings.data === 'undefined' || uri.query) {
244
+ settings.url = add_query_nonce(uri, nonce);
245
+ } else {
246
+ var data = settings.data ? settings.data.split('&') : [],
247
+ callback = check_ajax(location.pathname);
248
+ if (callback) {
249
+ data = callback(data);
250
+ }
251
+ data.push(IP_GEO_BLOCK_ZEP.auth + '=' + encodeURIComponent(nonce));//RFC3986
252
+ settings.data = data.join('&');
253
+ }
254
+ }
255
+ }
256
+ });
257
+
258
+ /*
259
+ * jQuery.bind-first library v0.2.3 (jquery >= 1.7)
260
+ * Copyright (c) 2013 Vladimir Zhuravlev
261
+ *
262
+ * Released under MIT License
263
+ * @license https://github.com/private-face/jquery.bind-first
264
+ *
265
+ * Date: Thu Feb 6 10:13:59 ICT 2014
266
+ */
267
+ function moveHandlerToTop($el, eventName, isDelegated) {
268
+ var data = $._data($el[0]).events,
269
+ events = data[eventName],
270
+ handler = isDelegated ? events.splice(events.delegateCount - 1, 1)[0] : events.pop();
271
+
272
+ events.splice(isDelegated ? 0 : (events.delegateCount || 0), 0, handler);
273
+ }
274
+
275
+ function moveEventHandlers($elems, eventsString, isDelegate) {
276
+ var events = eventsString.split(/\s+/);
277
+ $elems.each(function(i) {
278
+ for (i = 0; i < events.length; i++) {
279
+ var pureEventName = $.trim(events[i]).match(/[^\.]+/i)[0];
280
+ moveHandlerToTop($(this), pureEventName, isDelegate);
281
+ }
282
+ });
283
+ }
284
+
285
+ if (typeof $.fn.onFirst === 'undefined') {
286
+ $.fn.onFirst = function(types, selector) {
287
+ var type, $el = $(this),
288
+ isDelegated = typeof selector === 'string';
289
+
290
+ $.fn.on.apply($el, arguments);
291
+
292
+ // events map
293
+ if (typeof types === 'object') {
294
+ for (type in types) {
295
+ if (types.hasOwnProperty(type)) {
296
+ moveEventHandlers($el, type, isDelegated);
297
+ }
298
+ }
299
+ } else if (typeof types === 'string') {
300
+ moveEventHandlers($el, types, isDelegated);
301
+ }
302
+
303
+ return $el;
304
+ };
305
+ }
306
+
307
+ function attach_nonce() {
308
+ var nonce = IP_GEO_BLOCK_ZEP.nonce;
309
+ if (nonce) {
310
+ var $body = $('body');
311
+
312
+ $body.find('img').each(function (index) {
313
+ var src = $(this).attr('src');
314
+
315
+ // if admin area
316
+ if (is_admin(src) === 1) {
317
+ $(this).attr('src', add_query_nonce(src, nonce));
318
+ }
319
+ });
320
+
321
+ $body.onFirst('click contextmenu', 'a', function (event) {
322
+ // attr() returns 'string' or 'undefined'
323
+ var $this = $(this),
324
+ href = $this.attr('href'),
325
+ rel = $this.attr('rel'),
326
+ admin = "undefined" !== typeof href ? is_admin(href) : 0;
327
+
328
+ // if admin area (except in comment) then add a nonce
329
+ if (admin === 1) {
330
+ $this.attr('href', add_query_nonce(
331
+ href, (!rel || rel.indexOf('nofollow') < 0 ? nonce : 'nofollow')
332
+ ));
333
+ }
334
+
335
+ // if external then redirect with no referrer not to leak out the nonce
336
+ else if (admin === -1) {
337
+ var w = window.open();
338
+ w.document.write(
339
+ '<meta name="referrer" content="never" />' +
340
+ '<meta name="referrer" content="no-referrer" />' +
341
+ '<meta http-equiv="refresh" content="0; url=' + sanitize(this.href) + '" />'
342
+ );
343
+ w.document.close();
344
+
345
+ // stop event propagation
346
+ $this.removeAttr('target');
347
+ $this.off('click contextmenu');
348
+ event.preventDefault();
349
+ event.stopPropagation();
350
+ event.stopImmediatePropagation();
351
+ return false;
352
+ }
353
+ });
354
+
355
+ $body.onFirst('submit', 'form', function (event) {
356
+ var $this = $(this),
357
+ action = $this.attr('action'); // possibly 'undefined'
358
+
359
+ // if admin area then add the nonce
360
+ if (is_admin(action) === 1) {
361
+ $this.attr('action', add_query_nonce(action, nonce));
362
+ }
363
+ });
364
+
365
+ // Restore post revisions (wp-admin/revisions.php @since 2.6.0)
366
+ if ("undefined" !== typeof _wpRevisionsSettings) {
367
+ var i, data = _wpRevisionsSettings.revisionData, n = data.length;
368
+ for (i = 0; i < n; i++) {
369
+ if (-1 === data[i].restoreUrl.indexOf(IP_GEO_BLOCK_ZEP.auth)) {
370
+ _wpRevisionsSettings.revisionData[i].restoreUrl = add_query_nonce(data[i].restoreUrl, nonce);
371
+ }
372
+ }
373
+ }
374
+ }
375
+ }
376
+
377
+ $(function () {
378
+ // avoid conflict with "Open external links in a new window"
379
+ $('a').each(function () {
380
+ if(!this.hasAttribute('onClick')) {
381
+ this.setAttribute('onClick', 'javascript:void(0);');
382
+ }
383
+ });
384
+
385
+ // attach event to add nonce
386
+ attach_nonce();
387
+ IP_GEO_BLOCK_ZEP.init = true;
388
+ });
389
+
390
+ // fallback on error
391
+ $(window).on('error', function () {
392
+ if (!IP_GEO_BLOCK_ZEP.init) {
393
+ attach_nonce();
394
+ }
395
+ });
396
+ }(jQuery, document));
admin/js/authenticate.min.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ /*
2
+ Project: WP-ZEP - Zero-day exploit Prevention for wp-admin
3
+ Copyright (c) 2015-2016 tokkonopapa (tokkonopapa@yahoo.com)
4
+ This software is released under the MIT License.
5
+ */
6
+ var IP_GEO_BLOCK_ZEP={init:!1,auth:"ip-geo-block-auth-nonce",nonce:IP_GEO_BLOCK_AUTH.nonce||"",redirect:function(e){-1!==location.href.indexOf(e)&&(this.nonce&&(e+=(0<=e.indexOf("?")?"&":"?")+this.auth+"="+this.nonce),window.location.href=e)}};(function(e,r){function t(a){return a?a.toString().replace(/[&<>"']/g,function(a){return{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[a]}):""}function g(a){a=a?a.toString():"";a=a.match(/^(?:([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/);return{scheme:a[1]||"",relative:a[2]||"",authority:a[3]||"",path:a[4]||"",query:a[5]||"",fragment:a[6]||""}}function h(a,b){"object"!==typeof a&&(a=g(a||location.href));for(var c=a.query?a.query.split("&"):[],d=c.length;0<d--;)if(0===c[d].indexOf(IP_GEO_BLOCK_ZEP.auth)){c.splice(d,1);break}c.push(IP_GEO_BLOCK_ZEP.auth+"="+encodeURIComponent(b));a.query=c.join("&");return(a.scheme?a.scheme+":":"")+(a.relative+a.path)+(a.query?"?"+a.query:"")+(a.fragment?"#"+a.fragment:"")}function k(a){a=g(a?a.toString().toLowerCase():location.pathname);var b,c=a,d=[];"object"!==typeof c&&(c=g(c));c=c.path;"/"!==c.charAt(0)&&(b=window.location.pathname,c=b.substring(0,b.lastIndexOf("/")+1)+c);c=c.split("/");""===c[c.length-1]&&(c.pop(),c[c.length-1]+="/");for(b in c)c.hasOwnProperty(b)&&"."!==c[b]&&(".."===c[b]?0<d.length&&d.pop():(1>d.length||""!==c[b])&&d.push(c[b]));b=d.join("/").replace(/\/\//g,"/");if(/https?/.test(a.scheme)||!a.scheme){if(a.authority&&a.authority!==location.host.toLowerCase())return-1;if((a.scheme||a.path||a.query)&&u.test(b))return 1}return 0}function m(a,b,c){var d=b.split(/\s+/);a.each(function(a){for(a=0;a<d.length;a++){var b=e.trim(d[a]).match(/[^\.]+/i)[0],f=e(this),l=b,b=c,f=e._data(f[0]).events[l],l=b?f.splice(f.delegateCount-1,1)[0]:f.pop();f.splice(b?0:f.delegateCount||0,0,l)}})}function n(){var a=IP_GEO_BLOCK_ZEP.nonce;if(a){var b=e("body");b.find("img").each(function(b){b=e(this).attr("src");1===k(b)&&e(this).attr("src",h(b,a))});b.onFirst("click contextmenu","a",function(b){var c=e(this),d=c.attr("href"),f=c.attr("rel"),g="undefined"!==typeof d?k(d):0;if(1===g)c.attr("href",h(d,!f||0>f.indexOf("nofollow")?a:"nofollow"));else if(-1===g)return d=window.open(),d.document.write('<meta name="referrer" content="never" /><meta name="referrer" content="no-referrer" /><meta http-equiv="refresh" content="0; url='+t(this.href)+'" />'),d.document.close(),c.removeAttr("target"),c.off("click contextmenu"),b.preventDefault(),b.stopPropagation(),b.stopImmediatePropagation(),!1});b.onFirst("submit","form",function(b){b=e(this);var c=b.attr("action");1===k(c)&&b.attr("action",h(c,a))});if("undefined"!==typeof _wpRevisionsSettings)for(var c=_wpRevisionsSettings.revisionData,d=c.length,b=0;b<d;b++)-1===c[b].restoreUrl.indexOf(IP_GEO_BLOCK_ZEP.auth)&&(_wpRevisionsSettings.revisionData[b].restoreUrl=h(c[b].restoreUrl,a))}}var u=new RegExp("^(?:"+(IP_GEO_BLOCK_AUTH.home||"")+IP_GEO_BLOCK_AUTH.admin+"|"+(IP_GEO_BLOCK_AUTH.home||"")+IP_GEO_BLOCK_AUTH.plugins+"|"+(IP_GEO_BLOCK_AUTH.home||"")+IP_GEO_BLOCK_AUTH.themes+")(?:.*.php|.*/)?$"),p=function(a){for(var b=a.length;0<b--;)if(-1!==a[b].indexOf("request%5Bbrowse%5D=ip-geo-block-auth")){a[b]="request%5Bbrowse%5D=featured";break}return a},q={"upload.php":function(a){for(var b=a.length;0<b--;)if(-1!==a[b].indexOf("query%5Bip-geo-block-auth-nonce%5D=")){delete a[b];break}return a},"theme-install.php":p,"network/theme-install.php":p};e(r).ajaxSend(function(a,b,c){if((a=IP_GEO_BLOCK_ZEP.nonce)&&1===k(c.url))if("undefined"!==typeof window.FormData&&c.data instanceof FormData)c.data.append(IP_GEO_BLOCK_ZEP.auth,a);else if(b=g(c.url),"undefined"===typeof c.data||b.query)c.url=h(b,a);else{b=c.data?c.data.split("&"):[];var d;d=location.pathname;d=d.replace(IP_GEO_BLOCK_AUTH.home+IP_GEO_BLOCK_AUTH.admin,"");(d=q.hasOwnProperty(d)?q[d]:null)&&(b=d(b));b.push(IP_GEO_BLOCK_ZEP.auth+"="+encodeURIComponent(a));c.data=b.join("&")}});"undefined"===typeof e.fn.onFirst&&(e.fn.onFirst=function(a,b){var c,d=e(this),f="string"===typeof b;e.fn.on.apply(d,arguments);if("object"===typeof a)for(c in a)a.hasOwnProperty(c)&&m(d,c,f);else"string"===typeof a&&m(d,a,f);return d});e(function(){e("a").each(function(){this.hasAttribute("onClick")||this.setAttribute("onClick","javascript:void(0);")});n();IP_GEO_BLOCK_ZEP.init=!0});e(window).on("error",function(){IP_GEO_BLOCK_ZEP.init||n()})})(jQuery,document);
admin/js/footable.min.js ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * FooTable - Awesome Responsive Tables
3
+ * Version : 2.0.3
4
+ * http://fooplugins.com/plugins/footable-jquery/
5
+ *
6
+ * Requires jQuery - http://jquery.com/
7
+ *
8
+ * Copyright 2014 Steven Usher & Brad Vincent
9
+ * Released under the MIT license
10
+ * You are free to use FooTable in commercial projects as long as this copyright header is left intact.
11
+ *
12
+ * Date: 11 Nov 2014
13
+ *
14
+ * This is a customized version for IP Geo Block.
15
+ * footable.js + footable.paginate.js + footable.sort.js + footable.striping.js + footable.filter.js
16
+ * https://github.com/fooplugins/FooTable/issues/298
17
+ */
18
+ (function(d,m,w){function t(){var d=this;d.id=null;d.busy=!1;d.start=function(g,h){d.busy||(d.stop(),d.id=setTimeout(function(){g();d.id=null;d.busy=!1},h),d.busy=!0)};d.stop=function(){null!==d.id&&(clearTimeout(d.id),d.id=null,d.busy=!1)}}function v(a,g,h){var b=this;b.id=h;b.table=a;b.options=g;b.breakpoints=[];b.breakpointNames="";b.columns={};b.plugins=m.footable.plugins.load(b);var l=b.options,e=l.classes,n=l.events,k=l.triggers,r=0;b.timers={resize:new t,register:function(c){b.timers[c]=new t;return b.timers[c]}};b.init=function(){var c=d(m),f=d(b.table);m.footable.plugins.init(b);if(f.hasClass(e.loaded))b.raise(n.alreadyInitialized);else{b.raise(n.initializing);f.addClass(e.loading);f.find(l.columnDataSelector).each(function(){var c=b.getColumnData(this);b.columns[c.index]=c});for(var a in l.breakpoints)b.breakpoints.push({name:a,width:l.breakpoints[a]}),b.breakpointNames+=a+" ";b.breakpoints.sort(function(b,c){return b.width-c.width});f.unbind(k.initialize).bind(k.initialize,function(){f.removeData("footable_info");f.data("breakpoint","");f.trigger(k.resize);f.removeClass(e.loading);f.addClass(e.loaded).addClass(e.main);b.raise(n.initialized)}).unbind(k.redraw).bind(k.redraw,function(){b.redraw()}).unbind(k.resize).bind(k.resize,function(){b.resize()}).unbind(k.expandFirstRow).bind(k.expandFirstRow,function(){f.find(l.toggleSelector).first().not("."+e.detailShow).trigger(k.toggleRow)}).unbind(k.expandAll).bind(k.expandAll,function(){f.find(l.toggleSelector).not("."+e.detailShow).trigger(k.toggleRow)}).unbind(k.collapseAll).bind(k.collapseAll,function(){f.find("."+e.detailShow).trigger(k.toggleRow)});f.trigger(k.initialize);c.bind("resize.footable",function(){b.timers.resize.stop();b.timers.resize.start(function(){b.raise(k.resize)},l.delay)})}};b.addRowToggle=function(){if(l.addRowToggle){var c=d(b.table);c.find("span."+e.toggle).remove();for(var f in b.columns){var a=b.columns[f];if(a.toggle){c=c.find("> tbody");a="> tr:not(."+e.detail+",."+e.disabled+") > td:nth-child("+(parseInt(a.index,10)+1)+"),> tr:not(."+e.detail+",."+e.disabled+") > th:nth-child("+(parseInt(a.index,10)+1)+")";c.find(a).not("."+e.detailCell).prepend(d(l.toggleHTMLElement).addClass(e.toggle));return}}c.find("> tbody > tr:not(."+e.detail+",."+e.disabled+") > td:first-child").add("> tbody > tr:not(."+e.detail+",."+e.disabled+") > th:first-child").not("."+e.detailCell).prepend(d(l.toggleHTMLElement).addClass(e.toggle))}};b.setColumnClasses=function(){var c=d(b.table),f;for(f in b.columns){var a=b.columns[f];if(null!==a.className){var q="",p=!0;d.each(a.matches,function(b,c){p||(q+=", ");q+="> tbody > tr:not(."+e.detail+") > td:nth-child("+(parseInt(c,10)+1)+")";p=!1});c.find(q).not("."+e.detailCell).addClass(a.className)}}};b.bindToggleSelectors=function(){var c=d(b.table);b.hasAnyBreakpointColumn()&&(c.find(l.toggleSelector).unbind(k.toggleRow).bind(k.toggleRow,function(c){c=d(this).is("tr")?d(this):d(this).parents("tr:first");b.toggleDetail(c)}),c.find(l.toggleSelector).unbind("click.footable").bind("click.footable",function(b){c.is(".breakpoint")&&d(b.target).is("td,th,."+e.toggle)&&d(this).trigger(k.toggleRow)}))};b.parse=function(b,f){return(l.parsers[f.type]||l.parsers.alpha)(b)};b.getColumnData=function(c){var f=d(c),a=f.data("hide"),e=f.index(),a=jQuery.map((a||"").split(","),function(b){return jQuery.trim(b)}),e={index:e,hide:{},type:f.data("type")||"alpha",name:f.data("name")||d.trim(f.text()),ignore:f.data("ignore")||!1,toggle:f.data("toggle")||!1,className:f.data("class")||null,matches:[],names:{},group:f.data("group")||null,groupName:null,isEditable:f.data("editable")};if(null!==e.group){var p=d(b.table).find('> thead > tr.footable-group-row > th[data-group="'+e.group+'"], > thead > tr.footable-group-row > td[data-group="'+e.group+'"]').first();e.groupName=b.parse(p,{type:"alpha"})}p=parseInt(f.prev().attr("colspan")||0,10);r+=1<p?p-1:0;var p=parseInt(f.attr("colspan")||0,10),g=e.index+r;if(1<p)for(var h=f.data("names"),h=(h||"").split(","),k=0;k<p;k++)e.matches.push(k+g),k<h.length&&(e.names[k+g]=h[k]);else e.matches.push(g);e.hide["default"]="all"===f.data("hide")||0<=d.inArray("default",a);var p=!1,m;for(m in l.breakpoints)e.hide[m]="all"===f.data("hide")||0<=d.inArray(m,a),p=p||e.hide[m];e.hasBreakpoint=p;return b.raise(n.columnData,{column:{data:e,th:c}}).column.data};b.getViewportWidth=function(){return window.innerWidth||(document.body?document.body.offsetWidth:0)};b.calculateWidth=function(b,f){if(jQuery.isFunction(l.calculateWidthOverride))return l.calculateWidthOverride(b,f);f.viewportWidth<f.width&&(f.width=f.viewportWidth);f.parentWidth<f.width&&(f.width=f.parentWidth);return f};b.hasBreakpointColumn=function(c){for(var f in b.columns)if(b.columns[f].hide[c]&&!b.columns[f].ignore)return!0;return!1};b.hasAnyBreakpointColumn=function(){for(var c in b.columns)if(b.columns[c].hasBreakpoint)return!0;return!1};b.resize=function(){var c=d(b.table);if(c.is(":visible"))if(b.hasAnyBreakpointColumn()){var f={width:c.width(),viewportWidth:b.getViewportWidth(),parentWidth:c.parent().width()},f=b.calculateWidth(c,f),a=c.data("footable_info");c.data("footable_info",f);b.raise(n.resizing,{old:a,info:f});if(!a||a&&a.width&&a.width!==f.width){for(var e=null,g,h=0;h<b.breakpoints.length;h++)if((g=b.breakpoints[h])&&g.width&&f.width<=g.width){e=g;break}e=null===e?"default":e.name;g=b.hasBreakpointColumn(e);h=c.data("breakpoint");c.data("breakpoint",e).removeClass("default breakpoint").removeClass(b.breakpointNames).addClass(e+(g?" breakpoint":""));e!==h&&(c.trigger(k.redraw),b.raise(n.breakpoint,{breakpoint:e,info:f}))}b.raise(n.resized,{old:a,info:f})}else c.trigger(k.redraw)};b.redraw=function(){b.addRowToggle();b.bindToggleSelectors();b.setColumnClasses();var c=d(b.table),f=c.data("breakpoint"),a=b.hasBreakpointColumn(f);c.find("> tbody > tr:not(."+e.detail+")").data("detail_created",!1).end().find("> thead > tr:last-child > th").each(function(){var a=b.columns[d(this).index()],g="",h=!0;d.each(a.matches,function(b,c){h||(g+=", ");var a=c+1;g+="> tbody > tr:not(."+e.detail+") > td:nth-child("+a+")";g+=", > tfoot > tr:not(."+e.detail+") > td:nth-child("+a+")";g+=", > colgroup > col:nth-child("+a+")";h=!1});var g=g+(', > thead > tr[data-group-row="true"] > th[data-group="'+a.group+'"]'),k=c.find(g).add(this);""!==f&&(!1===a.hide[f]?k.addClass("footable-visible").show():k.removeClass("footable-visible").hide());if(1===c.find("> thead > tr.footable-group-row").length){var k=c.find('> thead > tr:last-child > th[data-group="'+a.group+'"]:visible, > thead > tr:last-child > th[data-group="'+a.group+'"]:visible'),a=c.find('> thead > tr.footable-group-row > th[data-group="'+a.group+'"], > thead > tr.footable-group-row > td[data-group="'+a.group+'"]'),l=0;d.each(k,function(){l+=parseInt(d(this).attr("colspan")||1,10)});0<l?a.attr("colspan",l).show():a.hide()}}).end().find("> tbody > tr."+e.detailShow).each(function(){b.createOrUpdateDetailRow(this)});c.find("[data-bind-name]").each(function(){b.toggleInput(this)});c.find("> tbody > tr."+e.detailShow+":visible").each(function(){var b=d(this).next();b.hasClass(e.detail)&&(a?b.show():b.hide())});c.find("> thead > tr > th.footable-last-column, > tbody > tr > td.footable-last-column").removeClass("footable-last-column");c.find("> thead > tr > th.footable-first-column, > tbody > tr > td.footable-first-column").removeClass("footable-first-column");c.find("> thead > tr, > tbody > tr").find("> th.footable-visible:last, > td.footable-visible:last").addClass("footable-last-column").end().find("> th.footable-visible:first, > td.footable-visible:first").addClass("footable-first-column");b.raise(n.redrawn)};b.toggleDetail=function(c){c=c.jquery?c:d(c);var a=c.next();c.hasClass(e.detailShow)?(c.removeClass(e.detailShow),a.hasClass(e.detail)&&a.hide(),b.raise(n.rowCollapsed,{row:c[0]})):(b.createOrUpdateDetailRow(c[0]),c.addClass(e.detailShow).next().show(),b.raise(n.rowExpanded,{row:c[0]}))};b.removeRow=function(c){c=c.jquery?c:d(c);c.hasClass(e.detail)&&(c=c.prev());var a=c.next();!0===c.data("detail_created")&&a.remove();c.remove();b.raise(n.rowRemoved)};b.appendRow=function(c){c=c.jquery?c:d(c);d(b.table).find("tbody").append(c);b.redraw()};b.getColumnFromTdIndex=function(c){var a=null,e;for(e in b.columns)if(0<=d.inArray(c,b.columns[e].matches)){a=b.columns[e];break}return a};b.createOrUpdateDetailRow=function(c){c=d(c);var a=c.next(),g,h=[];if(!0===c.data("detail_created"))return!0;if(c.is(":hidden"))return!1;b.raise(n.rowDetailUpdating,{row:c,detail:a});c.find("> td:hidden").each(function(){var c=d(this).index(),a=b.getColumnFromTdIndex(c),f=a.name;if(!0===a.ignore)return!0;c in a.names&&(f=a.names[c]);var g=d(this).attr("data-bind-name");if(null!=g&&d(this).is(":empty")){var k=d("."+e.detailInnerValue+'[data-bind-value="'+g+'"]');d(this).html(d(k).contents().detach())}var l;!1!==a.isEditable&&(a.isEditable||0<d(this).find(":input").length)&&(null==g&&(g="bind-"+d.now()+"-"+c,d(this).attr("data-bind-name",g)),l=d(this).contents().detach());l||(l=d(this).contents().clone(!0,!0));h.push({name:f,value:b.parse(this,a),display:l,group:a.group,groupName:a.groupName,bindName:g});return!0});if(0===h.length)return!1;g=c.find("> td:visible").length;var k=a.hasClass(e.detail);k||(a=d('<tr class="'+e.detail+'"><td class="'+e.detailCell+'"><div class="'+e.detailInner+'"></div></td></tr>'),c.after(a));a.find("> td:first").attr("colspan",g);g=a.find("."+e.detailInner).empty();l.createDetail(g,h,l.createGroupedDetail,l.detailSeparator,e);c.data("detail_created",!0);b.raise(n.rowDetailUpdated,{row:c,detail:a});return!k};b.raise=function(a,e){!0===b.options.debug&&d.isFunction(b.options.log)&&b.options.log(a,"event");e=e||{};var g={ft:b};d.extend(!0,g,e);var h=d.Event(a,g);h.ft||d.extend(!0,h,g);d(b.table).trigger(h);return h};b.reset=function(){var a=d(b.table);a.removeData("footable_info").data("breakpoint","").removeClass(e.loading).removeClass(e.loaded);a.find(l.toggleSelector).unbind(k.toggleRow).unbind("click.footable");a.find("> tbody > tr").removeClass(e.detailShow);a.find("> tbody > tr."+e.detail).remove();b.raise(n.reset)};b.toggleInput=function(b){var a=d(b).attr("data-bind-name");null!=a&&(a=d("."+e.detailInnerValue+'[data-bind-value="'+a+'"]'),null!=a&&(d(b).is(":visible")?d(a).is(":empty")||d(b).html(d(a).contents().detach()):d(b).is(":empty")||d(a).html(d(b).contents().detach())))};b.init();return b}m.footable={options:{delay:100,breakpoints:{phone:480,tablet:1024},parsers:{alpha:function(a){return d(a).data("value")||d.trim(d(a).text())},numeric:function(a){a=d(a).data("value")||d(a).text().replace(/[^0-9.\-]/g,"");a=parseFloat(a);isNaN(a)&&(a=0);return a}},addRowToggle:!0,calculateWidthOverride:null,toggleSelector:" > tbody > tr:not(.footable-row-detail)",columnDataSelector:"> thead > tr:last-child > th, > thead > tr:last-child > td",detailSeparator:":",toggleHTMLElement:"<span />",createGroupedDetail:function(a){for(var d={_none:{name:null,data:[]}},h=0;h<a.length;h++){var b=a[h].group;null!==b?(b in d||(d[b]={name:a[h].groupName||a[h].group,data:[]}),d[b].data.push(a[h])):d._none.data.push(a[h])}return d},createDetail:function(a,g,h,b,l){g=h(g);for(var e in g)if(0!==g[e].data.length)for("_none"!==e&&a.append('<div class="'+l.detailInnerGroup+'">'+g[e].name+"</div>"),h=0;h<g[e].data.length;h++){var m=g[e].data[h].name?b:"";a.append(d("<div></div>").addClass(l.detailInnerRow).append(d("<div></div>").addClass(l.detailInnerName).append(g[e].data[h].name+m)).append(d("<div></div>").addClass(l.detailInnerValue).attr("data-bind-value",g[e].data[h].bindName).append(g[e].data[h].display)))}},classes:{main:"footable",loading:"footable-loading",loaded:"footable-loaded",toggle:"footable-toggle",disabled:"footable-disabled",detail:"footable-row-detail",detailCell:"footable-row-detail-cell",detailInner:"footable-row-detail-inner",detailInnerRow:"footable-row-detail-row",detailInnerGroup:"footable-row-detail-group",detailInnerName:"footable-row-detail-name",detailInnerValue:"footable-row-detail-value",detailShow:"footable-detail-show"},triggers:{initialize:"footable_initialize",resize:"footable_resize",redraw:"footable_redraw",toggleRow:"footable_toggle_row",expandFirstRow:"footable_expand_first_row",expandAll:"footable_expand_all",collapseAll:"footable_collapse_all"},events:{alreadyInitialized:"footable_already_initialized",initializing:"footable_initializing",initialized:"footable_initialized",resizing:"footable_resizing",resized:"footable_resized",redrawn:"footable_redrawn",breakpoint:"footable_breakpoint",columnData:"footable_column_data",rowDetailUpdating:"footable_row_detail_updating",rowDetailUpdated:"footable_row_detail_updated",rowCollapsed:"footable_row_collapsed",rowExpanded:"footable_row_expanded",rowRemoved:"footable_row_removed",reset:"footable_reset"},debug:!1,log:null},version:{major:0,minor:5,toString:function(){return m.footable.version.major+"."+m.footable.version.minor},parse:function(a){a=/(\d+)\.?(\d+)?\.?(\d+)?/.exec(a);return{major:parseInt(a[1],10)||0,minor:parseInt(a[2],10)||0,patch:parseInt(a[3],10)||0}}},plugins:{_validate:function(a){if(!d.isFunction(a))return!0===m.footable.options.debug&&console.error('Validation failed, expected type "function", received type "{0}".',typeof a),!1;a=new a;if("string"!==typeof a.name)return!0===m.footable.options.debug&&console.error('Validation failed, plugin does not implement a string property called "name".',a),!1;if(!d.isFunction(a.init))return!0===m.footable.options.debug&&console.error('Validation failed, plugin "'+a.name+'" does not implement a function called "init".',a),!1;!0===m.footable.options.debug&&console.log('Validation succeeded for plugin "'+a.name+'".',a);return!0},registered:[],register:function(a,g){m.footable.plugins._validate(a)&&(m.footable.plugins.registered.push(a),"object"===typeof g&&d.extend(!0,m.footable.options,g))},load:function(a){var d=[],h,b;for(b=0;b<m.footable.plugins.registered.length;b++)try{h=m.footable.plugins.registered[b],d.push(new h(a))}catch(l){!0===m.footable.options.debug&&console.error(l)}return d},init:function(a){for(var d=0;d<a.plugins.length;d++)try{a.plugins[d].init(a)}catch(h){!0===m.footable.options.debug&&console.error(h)}}}};var u=0;d.fn.footable=function(a){a=a||{};var g=d.extend(!0,{},m.footable.options,a);return this.each(function(){u++;var a=new v(this,g,u);d(this).data("footable",a)})}})(jQuery,window);
19
+ /* pagenate */
20
+ (function(e,t,undefined){function a(t){var a=e(t.table),i=a.data();this.pageNavigation=i.pageNavigation||t.options.pageNavigation,this.pageSize=i.pageSize||t.options.pageSize,this.firstText=i.firstText||t.options.firstText,this.previousText=i.previousText||t.options.previousText,this.nextText=i.nextText||t.options.nextText,this.lastText=i.lastText||t.options.lastText,this.limitNavigation=parseInt(i.limitNavigation||t.options.limitNavigation||o.limitNavigation,10),this.limitPreviousText=i.limitPreviousText||t.options.limitPreviousText,this.limitNextText=i.limitNextText||t.options.limitNextText,this.limit=this.limitNavigation>0,this.currentPage=i.currentPage||0,this.pages=[],this.control=!1}function i(){var t=this;t.name="Footable Paginate",t.init=function(a){if(a.options.paginate===!0){if(e(a.table).data("page")===!1)return;t.footable=a,e(a.table).unbind(".paging").bind({"footable_initialized.paging footable_row_removed.paging footable_redrawn.paging footable_sorted.paging footable_filtered.paging":function(){t.setupPaging()}}).data("footable-paging",t)}},t.setupPaging=function(){var i=t.footable,o=e(i.table).find("> tbody");i.pageInfo=new a(i),t.createPages(i,o),t.createNavigation(i,o),t.fillPage(i,o,i.pageInfo.currentPage)},t.createPages=function(t,a){var i=1,o=t.pageInfo,n=i*o.pageSize,r=[],l=[];o.pages=[];var d=a.find("> tr:not(.footable-filtered,.footable-row-detail)");d.each(function(e,t){r.push(t),e===n-1?(o.pages.push(r),i++,n=i*o.pageSize,r=[]):e>=d.length-d.length%o.pageSize&&l.push(t)}),l.length>0&&o.pages.push(l),o.currentPage>=o.pages.length&&(o.currentPage=o.pages.length-1),0>o.currentPage&&(o.currentPage=0),1===o.pages.length?e(t.table).addClass("no-paging"):e(t.table).removeClass("no-paging")},t.createNavigation=function(a){var i=e(a.table).find(a.pageInfo.pageNavigation);if(0===i.length){if(i=e(a.pageInfo.pageNavigation),i.parents("table:first").length>0&&i.parents("table:first")!==e(a.table))return;i.length>1&&a.options.debug===!0&&console.error("More than one pagination control was found!")}if(0!==i.length){i.is("ul")||(0===i.find("ul:first").length&&i.append("<ul />"),i=i.find("ul")),i.find("li").remove();var o=a.pageInfo;o.control=i,o.pages.length>0&&(i.append('<li class="footable-page-arrow"><a data-page="first" href="#first">'+a.pageInfo.firstText+"</a>"),i.append('<li class="footable-page-arrow"><a data-page="prev" href="#prev">'+a.pageInfo.previousText+"</a></li>"),o.limit&&i.append('<li class="footable-page-arrow"><a data-page="limit-prev" href="#limit-prev">'+a.pageInfo.limitPreviousText+"</a></li>"),o.limit||e.each(o.pages,function(e,t){t.length>0&&i.append('<li class="footable-page"><a data-page="'+e+'" href="#">'+(e+1)+"</a></li>")}),o.limit&&(i.append('<li class="footable-page-arrow"><a data-page="limit-next" href="#limit-next">'+a.pageInfo.limitNextText+"</a></li>"),t.createLimited(i,o,0)),i.append('<li class="footable-page-arrow"><a data-page="next" href="#next">'+a.pageInfo.nextText+"</a></li>"),i.append('<li class="footable-page-arrow"><a data-page="last" href="#last">'+a.pageInfo.lastText+"</a></li>")),i.off("click","a[data-page]").on("click","a[data-page]",function(n){n.preventDefault();var r=e(this).data("page"),l=o.currentPage;if("first"===r)l=0;else if("prev"===r)l>0&&l--;else if("next"===r)o.pages.length-1>l&&l++;else if("last"===r)l=o.pages.length-1;else if("limit-prev"===r){l=-1;var d=i.find(".footable-page:first a").data("page");t.createLimited(i,o,d-o.limitNavigation),t.setPagingClasses(i,o.currentPage,o.pages.length)}else if("limit-next"===r){l=-1;var s=i.find(".footable-page:last a").data("page");t.createLimited(i,o,s+1),t.setPagingClasses(i,o.currentPage,o.pages.length)}else l=r;if(l>=0){if(o.limit&&o.currentPage!=l){for(var f=l;0!==f%o.limitNavigation;)f-=1;t.createLimited(i,o,f)}t.paginate(a,l)}}),t.setPagingClasses(i,o.currentPage,o.pages.length)}},t.createLimited=function(e,t,a){a=a||0,e.find("li.footable-page").remove();var i,o,n=e.find('li.footable-page-arrow > a[data-page="limit-prev"]').parent(),r=e.find('li.footable-page-arrow > a[data-page="limit-next"]').parent();for(i=t.pages.length-1;i>=0;i--)o=t.pages[i],i>=a&&a+t.limitNavigation>i&&o.length>0&&n.after('<li class="footable-page"><a data-page="'+i+'" href="#">'+(i+1)+"</a></li>");0===a?n.hide():n.show(),a+t.limitNavigation>=t.pages.length?r.hide():r.show()},t.paginate=function(a,i){var o=a.pageInfo;if(o.currentPage!==i){var n=e(a.table).find("> tbody"),r=a.raise("footable_paging",{page:i,size:o.pageSize});if(r&&r.result===!1)return;t.fillPage(a,n,i),o.control.find("li").removeClass("active disabled"),t.setPagingClasses(o.control,o.currentPage,o.pages.length)}},t.setPagingClasses=function(e,t,a){e.find("li.footable-page > a[data-page="+t+"]").parent().addClass("active"),t>=a-1&&(e.find('li.footable-page-arrow > a[data-page="next"]').parent().addClass("disabled"),e.find('li.footable-page-arrow > a[data-page="last"]').parent().addClass("disabled")),1>t&&(e.find('li.footable-page-arrow > a[data-page="first"]').parent().addClass("disabled"),e.find('li.footable-page-arrow > a[data-page="prev"]').parent().addClass("disabled"))},t.fillPage=function(a,i,o){a.pageInfo.currentPage=o,e(a.table).data("currentPage",o),i.find("> tr").hide(),e(a.pageInfo.pages[o]).each(function(){t.showRow(this,a)}),a.raise("footable_page_filled")},t.showRow=function(t,a){var i=e(t),o=i.next(),n=e(a.table);n.hasClass("breakpoint")&&i.hasClass("footable-detail-show")&&o.hasClass("footable-row-detail")?(i.add(o).show(),a.createOrUpdateDetailRow(t)):i.show()}}if(t.footable===undefined||null===t.footable)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var o={paginate:!0,pageSize:10,pageNavigation:".pagination",firstText:"&laquo;",previousText:"&lsaquo;",nextText:"&rsaquo;",lastText:"&raquo;",limitNavigation:0,limitPreviousText:"...",limitNextText:"..."};t.footable.plugins.register(i,o)})(jQuery,window);
21
+ /* sort */
22
+ (function(t,e,undefined){function a(){var e=this;e.name="Footable Sortable",e.init=function(a){e.footable=a,a.options.sort===!0&&t(a.table).unbind(".sorting").bind({"footable_initialized.sorting":function(){var i,o,n=t(a.table),r=(n.find("> tbody"),a.options.classes.sort);if(n.data("sort")!==!1){n.find("> thead > tr:last-child > th, > thead > tr:last-child > td").each(function(){var e=t(this),i=a.columns[e.index()];i.sort.ignore===!0||e.hasClass(r.sortable)||(e.addClass(r.sortable),t("<span />").addClass(r.indicator).appendTo(e))}),n.find("> thead > tr:last-child > th."+r.sortable+", > thead > tr:last-child > td."+r.sortable).unbind("click.footable").bind("click.footable",function(a){a.preventDefault(),o=t(this);var i=!o.hasClass(r.sorted);return e.doSort(o.index(),i),!1});var l=!1;for(var s in a.columns)if(i=a.columns[s],i.sort.initial){var d="descending"!==i.sort.initial;e.doSort(i.index,d);break}l&&a.bindToggleSelectors()}},"footable_redrawn.sorting":function(){var i=t(a.table),o=a.options.classes.sort;i.data("sorted")>=0&&i.find("> thead > tr:last-child > th").each(function(a){var i=t(this);return i.hasClass(o.sorted)||i.hasClass(o.descending)?(e.doSort(a),undefined):undefined})},"footable_column_data.sorting":function(e){var a=t(e.column.th);e.column.data.sort=e.column.data.sort||{},e.column.data.sort.initial=a.data("sort-initial")||!1,e.column.data.sort.ignore=a.data("sort-ignore")||!1,e.column.data.sort.selector=a.data("sort-selector")||null;var i=a.data("sort-match")||0;i>=e.column.data.matches.length&&(i=0),e.column.data.sort.match=e.column.data.matches[i]}}).data("footable-sort",e)},e.doSort=function(a,i){var o=e.footable;if(t(o.table).data("sort")!==!1){var n=t(o.table),r=n.find("> tbody"),l=o.columns[a],s=n.find("> thead > tr:last-child > th:eq("+a+")"),d=o.options.classes.sort,f=o.options.events.sort;if(i=i===undefined?s.hasClass(d.sorted):"toggle"===i?!s.hasClass(d.sorted):i,l.sort.ignore===!0)return!0;var u=o.raise(f.sorting,{column:l,direction:i?"ASC":"DESC"});u&&u.result===!1||(n.data("sorted",l.index),n.find("> thead > tr:last-child > th, > thead > tr:last-child > td").not(s).removeClass(d.sorted+" "+d.descending),i===undefined&&(i=s.hasClass(d.sorted)),i?s.removeClass(d.descending).addClass(d.sorted):s.removeClass(d.sorted).addClass(d.descending),e.sort(o,r,l,i),o.bindToggleSelectors(),o.raise(f.sorted,{column:l,direction:i?"ASC":"DESC"}))}},e.rows=function(e,a,i){var o=[];return a.find("> tr").each(function(){var a=t(this),n=null;if(a.hasClass(e.options.classes.detail))return!0;a.next().hasClass(e.options.classes.detail)&&(n=a.next().get(0));var r={row:a,detail:n};return i!==undefined&&(r.value=e.parse(this.cells[i.sort.match],i)),o.push(r),!0}).detach(),o},e.sort=function(t,a,i,o){var n=e.rows(t,a,i),r=t.options.sorters[i.type]||t.options.sorters.alpha;n.sort(function(t,e){return o?r(t.value,e.value):r(e.value,t.value)});for(var l=0;n.length>l;l++)a.append(n[l].row),null!==n[l].detail&&a.append(n[l].detail)}}if(e.footable===undefined||null===e.footable)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var i={sort:!0,sorters:{alpha:function(t,e){return"string"==typeof t&&(t=t.toLowerCase()),"string"==typeof e&&(e=e.toLowerCase()),t===e?0:e>t?-1:1},numeric:function(t,e){return t-e}},classes:{sort:{sortable:"footable-sortable",sorted:"footable-sorted",descending:"footable-sorted-desc",indicator:"footable-sort-indicator"}},events:{sort:{sorting:"footable_sorting",sorted:"footable_sorted"}}};e.footable.plugins.register(a,i)})(jQuery,window);
23
+ /* striping */
24
+ (function(t,e,undefined){function a(){var e=this;e.name="Footable Striping",e.init=function(a){e.footable=a,t(a.table).unbind("striping").bind({"footable_initialized.striping footable_row_removed.striping footable_redrawn.striping footable_sorted.striping footable_filtered.striping":function(){t(this).data("striping")!==!1&&e.setupStriping(a)}})},e.setupStriping=function(e){var a=0;t(e.table).find("> tbody > tr:not(.footable-row-detail)").each(function(){var i=t(this);i.removeClass(e.options.classes.striping.even).removeClass(e.options.classes.striping.odd),0===a%2?i.addClass(e.options.classes.striping.even):i.addClass(e.options.classes.striping.odd),a++})}}if(e.footable===undefined||null===e.foobox)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var i={striping:{enabled:!0},classes:{striping:{odd:"footable-odd",even:"footable-even"}}};e.footable.plugins.register(a,i)})(jQuery,window);
25
+ /* filter */
26
+ (function(t,e,undefined){function a(){var e=this;e.name="Footable Filter",e.init=function(a){if(e.footable=a,a.options.filter.enabled===!0){if(t(a.table).data("filter")===!1)return;a.timers.register("filter"),t(a.table).unbind(".filtering").bind({"footable_initialized.filtering":function(){var i=t(a.table),o={input:i.data("filter")||a.options.filter.input,timeout:i.data("filter-timeout")||a.options.filter.timeout,minimum:i.data("filter-minimum")||a.options.filter.minimum,disableEnter:i.data("filter-disable-enter")||a.options.filter.disableEnter};o.disableEnter&&t(o.input).keypress(function(t){return window.event?13!==window.event.keyCode:13!==t.which}),i.bind("footable_clear_filter",function(){t(o.input).val(""),e.clearFilter()}),i.bind("footable_filter",function(t,a){e.filter(a.filter)}),t(o.input).keyup(function(i){a.timers.filter.stop(),27===i.which&&t(o.input).val(""),a.timers.filter.start(function(){var a=t(o.input).val()||"";e.filter(a)},o.timeout)})},"footable_redrawn.filtering":function(){var i=t(a.table),o=i.data("filter-string");o&&e.filter(o)}}).data("footable-filter",e)}},e.filter=function(a){var i=e.footable,o=t(i.table),n=o.data("filter-minimum")||i.options.filter.minimum,r=!a,l=i.raise("footable_filtering",{filter:a,clear:r});if(!(l&&l.result===!1||l.filter&&n>l.filter.length))if(l.clear)e.clearFilter();else{var d=l.filter.split(" ");o.find("> tbody > tr").hide().addClass("footable-filtered");var s=o.find("> tbody > tr:not(.footable-row-detail)");t.each(d,function(t,e){e&&e.length>0&&(o.data("current-filter",e),s=s.filter(i.options.filter.filterFunction))}),s.each(function(){e.showRow(this,i),t(this).removeClass("footable-filtered")}),o.data("filter-string",l.filter),i.raise("footable_filtered",{filter:l.filter,clear:!1})}},e.clearFilter=function(){var a=e.footable,i=t(a.table);i.find("> tbody > tr:not(.footable-row-detail)").removeClass("footable-filtered").each(function(){e.showRow(this,a)}),i.removeData("filter-string"),a.raise("footable_filtered",{clear:!0})},e.showRow=function(e,a){var i=t(e),o=i.next(),n=t(a.table);i.is(":visible")||(n.hasClass("breakpoint")&&i.hasClass("footable-detail-show")&&o.hasClass("footable-row-detail")?(i.add(o).show(),a.createOrUpdateDetailRow(e)):i.show())}}if(e.footable===undefined||null===e.footable)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var i={filter:{enabled:!0,input:".footable-filter",timeout:300,minimum:2,disableEnter:!1,filterFunction:function(){var e=t(this),a=e.parents("table:first"),i=a.data("current-filter").toUpperCase(),o=e.find("td").text();return a.data("filter-text-only")||e.find("td[data-value]").each(function(){o+=t(this).data("value")}),o.toUpperCase().indexOf(i)>=0}}};e.footable.plugins.register(a,i)})(jQuery,window);
admin/js/gmap.js ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Project: GmapRS - google map for WordPress IP Geo Block
3
+ * Description: A really simple google map plugin based on jQuery-boilerplate.
4
+ * Version: 0.2.4
5
+ * Copyright (c) 2013-2016 tokkonopapa (tokkonopapa@yahoo.com)
6
+ * This software is released under the MIT License.
7
+ */
8
+ // https://developers.google.com/maps/documentation/javascript/events?hl=en#auth-errors
9
+ function gm_authFailure() {
10
+ 'use strict';
11
+ jQuery(window).trigger('ip-geo-block-gmap-error');
12
+ }
13
+
14
+ (function ($) {
15
+ 'use strict';
16
+ $(function ($) {
17
+ var e = "GmapRS",
18
+ d = "plugin_" + e,
19
+ b = {
20
+ zoom: 2,
21
+ latitude: 0,
22
+ longitude: 0
23
+ },
24
+ i = google.maps,
25
+ h = function (j) {
26
+ this.o = $.extend({}, b);
27
+ this.q = [];
28
+ };
29
+ h.prototype = {
30
+ init: function (j) {
31
+ $.extend(this.o, j);
32
+ this.c = new i.LatLng(this.o.latitude, this.o.longitude);
33
+ this.m = new i.Map(this.e.get(0), {
34
+ zoom: this.o.zoom,
35
+ center: this.c,
36
+ mapTypeId: i.MapTypeId.ROADMAP
37
+ });
38
+ },
39
+ destroy: function () {
40
+ this.deleteMarkers();
41
+ this.e.data(d, null);
42
+ },
43
+ setCenter: function () {
44
+ if (arguments.length >= 2) {
45
+ var j = new i.LatLng((this.o.latitude = arguments[0]), (this.o.longitude = arguments[1]));
46
+ delete this.c;
47
+ this.c = j;
48
+ }
49
+ this.m.setCenter(this.c);
50
+ return this.e;
51
+ },
52
+ setZoom: function (j) {
53
+ this.m.setZoom(j || this.o.zoom);
54
+ return this.e;
55
+ },
56
+ showMarker: function (l, k) {
57
+ var j = this.q[l];
58
+ if (j && j.w) {
59
+ (false === k) ? j.w.close() : j.w.open(this.m, j.m);
60
+ }
61
+ },
62
+ addMarker: function (l) {
63
+ var m, j, k;
64
+ m = new i.LatLng(l.latitude || this.o.latitude, l.longitude || this.o.longitude);
65
+ j = new i.Marker({
66
+ position: m,
67
+ map: this.m,
68
+ title: l.title || ""
69
+ });
70
+ if (l.content) {
71
+ k = new i.InfoWindow({
72
+ content: l.content
73
+ });
74
+ i.event.addListener(j, "click", function () {
75
+ k.open(j.getMap(), j);
76
+ });
77
+ }
78
+ this.q.push({
79
+ p: m,
80
+ w: k,
81
+ m: j
82
+ });
83
+ this.m.setCenter(m);
84
+ this.m.setZoom(l.zoom);
85
+ if (l.show) {
86
+ this.showMarker(this.q.length - 1);
87
+ }
88
+ return this.e;
89
+ },
90
+ deleteMarkers: function () {
91
+ var j, k;
92
+ for (j in this.q) {
93
+ if (this.q.hasOwnProperty(j)) {
94
+ k = this.q[j];
95
+ k.m.setMap(null);
96
+ }
97
+ }
98
+ this.q.length = 0;
99
+ return this.e;
100
+ }
101
+ };
102
+ $.fn[e] = function (k) {
103
+ var l, j;
104
+ if (!(this.data(d) instanceof h)) {
105
+ this.data(d, new h(this));
106
+ }
107
+ j = this.data(d);
108
+ j.e = this;
109
+ if (typeof k === "undefined" || typeof k === "object") {
110
+ if (typeof j.init === "function") {
111
+ j.init(k);
112
+ }
113
+ } else {
114
+ if (typeof k === "string" && typeof j[k] === "function") {
115
+ l = Array.prototype.slice.call(arguments, 1);
116
+ return j[k].apply(j, l);
117
+ } else {
118
+ $.error("Method " + k + " does not exist." + e);
119
+ }
120
+ }
121
+ };
122
+ });
123
+ }(jQuery));
admin/js/gmap.min.js ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ /*
2
+ Project: GmapRS - google map for WordPress IP Geo Block
3
+ Description: A really simple google map plugin based on jQuery-boilerplate.
4
+ Version: 0.2.4
5
+ Copyright (c) 2013-2016 tokkonopapa (tokkonopapa@yahoo.com)
6
+ This software is released under the MIT License.
7
+ */
8
+ function gm_authFailure(){jQuery(window).trigger("ip-geo-block-gmap-error")}(function(f){f(function(d){var f={zoom:2,latitude:0,longitude:0},e=google.maps,g=function(a){this.o=d.extend({},f);this.q=[]};g.prototype={init:function(a){d.extend(this.o,a);this.c=new e.LatLng(this.o.latitude,this.o.longitude);this.m=new e.Map(this.e.get(0),{zoom:this.o.zoom,center:this.c,mapTypeId:e.MapTypeId.ROADMAP})},destroy:function(){this.deleteMarkers();this.e.data("plugin_GmapRS",null)},setCenter:function(){if(2<=arguments.length){var a=new e.LatLng(this.o.latitude=arguments[0],this.o.longitude=arguments[1]);delete this.c;this.c=a}this.m.setCenter(this.c);return this.e},setZoom:function(a){this.m.setZoom(a||this.o.zoom);return this.e},showMarker:function(a,c){var b=this.q[a];b&&b.w&&(!1===c?b.w.close():b.w.open(this.m,b.m))},addMarker:function(a){var c,b,d;c=new e.LatLng(a.latitude||this.o.latitude,a.longitude||this.o.longitude);b=new e.Marker({position:c,map:this.m,title:a.title||""});a.content&&(d=new e.InfoWindow({content:a.content}),e.event.addListener(b,"click",function(){d.open(b.getMap(),b)}));this.q.push({p:c,w:d,m:b});this.m.setCenter(c);this.m.setZoom(a.zoom);a.show&&this.showMarker(this.q.length-1);return this.e},deleteMarkers:function(){var a,c;for(a in this.q)this.q.hasOwnProperty(a)&&(c=this.q[a],c.m.setMap(null));this.q.length=0;return this.e}};d.fn.GmapRS=function(a){var c,b;this.data("plugin_GmapRS")instanceof g||this.data("plugin_GmapRS",new g(this));b=this.data("plugin_GmapRS");b.e=this;if("undefined"===typeof a||"object"===typeof a)"function"===typeof b.init&&b.init(a);else{if("string"===typeof a&&"function"===typeof b[a])return c=Array.prototype.slice.call(arguments,1),b[a].apply(b,c);d.error("Method "+a+" does not exist.GmapRS")}}})})(jQuery);
admin/js/whois.js ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*jslint white: true */
2
+ /*!
3
+ * Project: whois.js - get whois infomation
4
+ * Description: A jQuery plugin to get whois infomation from RIPE NCC database.
5
+ * Version: 0.1
6
+ * Copyright (c) 2016 tokkonopapa (tokkonopapa@yahoo.com)
7
+ * This software is released under the MIT License.
8
+ *
9
+ * RIPE NCC
10
+ * @link https://apps.db.ripe.net/search/query.html
11
+ * @link https://labs.ripe.net/ripe-database/database-api/api-documentation
12
+ * @link https://www.ripe.net/manage-ips-and-asns/db/support/documentation/ripe-database-documentation
13
+ * @link https://www.ripe.net/manage-ips-and-asns/db/support/documentation/ripe-database-documentation/how-to-query-the-ripe-database/14-3-restful-api-queries/14-3-2-api-search
14
+ * @link https://github.com/RIPE-NCC/whois/wiki/WHOIS-REST-API-search
15
+ */
16
+ (function ($) {
17
+ 'use strict';
18
+
19
+ $.extend({
20
+ whois: function (query, callback) {
21
+ /**
22
+ * APIs that doesn't support CORS.
23
+ * It is accessed through https://developer.yahoo.com/yql/
24
+ */
25
+ var results = [],
26
+ yql = 'https://query.yahooapis.com/v1/public/yql?q=select * from xml where url="%URL%"&format=json&jsonCompat=new',
27
+ url = 'https://rest.db.ripe.net/search%3fflags=no-filtering%26flags=resource%26query-string=';
28
+ // app = 'https://apps.db.ripe.net/search/lookup.html?source=%SRC%&key=%KEY%&type=%TYPE%';
29
+
30
+ function sanitize(str) {
31
+ return str ? str.toString().replace(/[&<>"']/g, function (match) {
32
+ return {
33
+ '&': '&amp;',
34
+ '<': '&lt;',
35
+ '>': '&gt;',
36
+ '"': '&quot;',
37
+ "'": '&#39;'
38
+ }[match];
39
+ }) : '';
40
+ }
41
+
42
+ return $.ajax({
43
+ url: yql.replace(/%URL%/, url + query),
44
+ method: 'GET',
45
+ dataType: 'json'
46
+ })
47
+
48
+ .done(function (data, textStatus, jqXHR) {
49
+ // http://stackoverflow.com/questions/722668/traverse-all-the-nodes-of-a-json-object-tree-with-javascript#answer-722676
50
+ function traverse(key, value) {
51
+ if (value && typeof value === 'object') {
52
+ if (value.errormessage) {
53
+ var err = value.errormessage,
54
+ msg = err.text.split(/\n+/);
55
+
56
+ results.push({
57
+ name : sanitize(err.severity),
58
+ value: sanitize(msg[1].replace(/%s/, err.args.value))
59
+ });
60
+ }
61
+
62
+ else if (value.href) {
63
+ value.href = sanitize(value.href);
64
+ results.push({
65
+ name : sanitize(key),
66
+ value: '<a href="' + value.href + '.json" target=_blank>' + value.href + '</a>'
67
+ });
68
+ }
69
+
70
+ else if (value.name && value.value) {
71
+ /*if (value.link) {
72
+ var src = value.link.href.match(/\w+-grs/);
73
+ value.value = '<a href="' +
74
+ app.replace('%SRC%', src[0])
75
+ .replace('%KEY%', encodeURI(value['value']))
76
+ .replace('%TYPE%', value['referenced-type']) +
77
+ '" target=_blank>' + value.value + '</a>';
78
+ }*/
79
+
80
+ if (value.link) {
81
+ value.value = '<a href="' + sanitize(value.link.href) + '.json" target=_blank>' + sanitize(value.value) + '</a>';
82
+ }
83
+
84
+ else if ('remarks' === value.name) {
85
+ value.value = sanitize(value.value);
86
+ value.value = value.value.replace(/(https?:\/\/[^\s]+)/gi, '<a href="$1" target=_blank>$1</a>');
87
+ }
88
+
89
+ results.push({
90
+ name : sanitize(value.name),
91
+ value: value.value
92
+ });
93
+ }
94
+
95
+ else if ('primary-key' !== key) {
96
+ $.each(value, function(k, v) {
97
+ // k is either an array index or object key
98
+ traverse(k, v);
99
+ });
100
+ }
101
+ }
102
+ }
103
+
104
+ var i, attr = data.query.results, objs = [];
105
+
106
+ for (i in attr) {
107
+ if (attr.hasOwnProperty(i)) {
108
+ objs = attr[i]; // whois-resouces
109
+ break;
110
+ }
111
+ }
112
+
113
+ traverse(null, objs);
114
+ })
115
+
116
+ .fail(function (jqXHR, textStatus, errorThrown) {
117
+ results.push({
118
+ name : sanitize(textStatus),
119
+ value: sanitize(errorThrown)
120
+ });
121
+ })
122
+
123
+ .always(function () {
124
+ results.push({
125
+ name : 'copyright',
126
+ value: '<a href="https://apps.db.ripe.net/search/query.html" title="Database Query - RIPE Network Coordination Centre">RIPE NCC</a>'
127
+ });
128
+
129
+ if (callback) {
130
+ callback(results);
131
+ }
132
+ });
133
+ }
134
+ });
135
+
136
+ })(jQuery);
admin/js/whois.min.js ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ /*
2
+ Project: whois.js - get whois infomation
3
+ Description: A jQuery plugin to get whois infomation from RIPE NCC database.
4
+ Version: 0.1
5
+ Copyright (c) 2016 tokkonopapa (tokkonopapa@yahoo.com)
6
+ This software is released under the MIT License.
7
+ */
8
+ (function(g){g.extend({whois:function(l,e){function b(b){return b?b.toString().replace(/[&<>"']/g,function(b){return{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[b]}):""}var f=[];return g.ajax({url:'https://query.yahooapis.com/v1/public/yql?q=select * from xml where url="%URL%"&format=json&jsonCompat=new'.replace(/%URL%/,"https://rest.db.ripe.net/search%3fflags=no-filtering%26flags=resource%26query-string="+l),method:"GET",dataType:"json"}).done(function(c,d,e){function k(c,a){if(a&&"object"===typeof a)if(a.errormessage){var d=a.errormessage,e=d.text.split(/\n+/);f.push({name:b(d.severity),value:b(e[1].replace(/%s/,d.args.value))})}else a.href?(a.href=b(a.href),f.push({name:b(c),value:'<a href="'+a.href+'.json" target=_blank>'+a.href+"</a>"})):a.name&&a.value?(a.link?a.value='<a href="'+b(a.link.href)+'.json" target=_blank>'+b(a.value)+"</a>":"remarks"===a.name&&(a.value=b(a.value),a.value=a.value.replace(/(https?:\/\/[^\s]+)/gi,'<a href="$1" target=_blank>$1</a>')),f.push({name:b(a.name),value:a.value})):"primary-key"!==c&&g.each(a,function(a,b){k(a,b)})}var h;c=c.query.results;d=[];for(h in c)if(c.hasOwnProperty(h)){d=c[h];break}k(null,d)}).fail(function(c,d,e){f.push({name:b(d),value:b(e)})}).always(function(){f.push({name:"copyright",value:'<a href="https://apps.db.ripe.net/search/query.html" title="Database Query - RIPE Network Coordination Centre">RIPE NCC</a>'});e&&e(f)})}})})(jQuery);
classes/class-ip-geo-block-actv.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IP Geo Block - Activate
4
+ *
5
+ * @package IP_Geo_Block
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2016 tokkonopapa
10
+ */
11
+
12
+ // Stuff for resources
13
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-util.php';
14
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php';
15
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php';
16
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-cron.php';
17
+ require_once IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-rewrite.php';
18
+
19
+ class IP_Geo_Block_Activate {
20
+
21
+ // initialize logs then upgrade and return new options
22
+ private static function activate_blog() {
23
+ IP_Geo_Block_Logs::create_tables();
24
+ IP_Geo_Block_Opts::upgrade();
25
+ }
26
+
27
+ // initialize main blog
28
+ public static function init_main_blog() {
29
+ if ( current_user_can( 'manage_options' ) ) {
30
+ $settings = IP_Geo_Block::get_option();
31
+
32
+ // kick off a cron job to download database immediately
33
+ IP_Geo_Block_Cron::start_update_db( $settings );
34
+ IP_Geo_Block_Cron::start_cache_gc( $settings );
35
+
36
+ // activate rewrite rules
37
+ IP_Geo_Block_Admin_Rewrite::activate_rewrite_all( $settings['rewrite'] );
38
+
39
+ // activate mu-plugins if needed
40
+ IP_Geo_Block_Opts::setup_validation_timing( $settings );
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Register options into database table when the plugin is activated.
46
+ *
47
+ */
48
+ public static function activate( $network_wide = FALSE ) {
49
+ if ( ! function_exists( 'is_plugin_active_for_network' ) )
50
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
51
+
52
+ if ( is_plugin_active_for_network( IP_GEO_BLOCK_BASE ) ) {
53
+ global $wpdb;
54
+ $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
55
+ $current_blog_id = get_current_blog_id();
56
+
57
+ foreach ( $blog_ids as $id ) {
58
+ switch_to_blog( $id );
59
+ self::activate_blog();
60
+ }
61
+
62
+ switch_to_blog( $current_blog_id );
63
+ }
64
+
65
+ else {
66
+ self::activate_blog();
67
+ }
68
+
69
+ // only after 'init' action hook for is_user_logged_in().
70
+ if ( did_action( 'init' ) && is_user_logged_in() )
71
+ self::init_main_blog(); // should be called with high priority
72
+ }
73
+
74
+ /**
75
+ * Fired when the plugin is deactivated.
76
+ *
77
+ */
78
+ public static function deactivate( $network_wide = FALSE ) {
79
+ // cancel schedule
80
+ IP_Geo_Block_Cron::stop_update_db();
81
+ IP_Geo_Block_Cron::stop_cache_gc();
82
+
83
+ // deactivate rewrite rules
84
+ IP_Geo_Block_Admin_Rewrite::deactivate_rewrite_all();
85
+
86
+ // deactivate mu-plugins
87
+ IP_Geo_Block_Opts::setup_validation_timing();
88
+ }
89
+
90
+ }
classes/class-ip-geo-block-apis.php ADDED
@@ -0,0 +1,688 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IP Geo Block - IP Address Geolocation API Class
4
+ *
5
+ * @package IP_Geo_Block
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2016 tokkonopapa
10
+ */
11
+
12
+ /**
13
+ * Service type
14
+ *
15
+ */
16
+ define( 'IP_GEO_BLOCK_API_TYPE_IPV4', 1 ); // can handle IPv4
17
+ define( 'IP_GEO_BLOCK_API_TYPE_IPV6', 2 ); // can handle IPv6
18
+ define( 'IP_GEO_BLOCK_API_TYPE_BOTH', 3 ); // can handle both IPv4 and IPv6
19
+
20
+ /**
21
+ * Abstract class
22
+ *
23
+ */
24
+ abstract class IP_Geo_Block_API {
25
+
26
+ /**
27
+ * These values must be instantiated in child class
28
+ *
29
+ *//*
30
+ protected $template = array(
31
+ 'type' => IP_GEO_BLOCK_API_TYPE_[IPV4 | IPV6 | BOTH],
32
+ 'url' => 'http://example.com/%API_KEY%/%API_FORMAT%/%API_OPTION%/%API_IP%';
33
+ 'api' => array(
34
+ '%API_IP%' => '', // should be set in build_url()
35
+ '%API_KEY%' => '', // should be set in __construct()
36
+ '%API_FORMAT%' => '', // may be set in child class
37
+ '%API_OPTION%' => '', // may be set in child class
38
+ ),
39
+ 'transform' => array(
40
+ 'errorMessage' => '',
41
+ 'countryCode' => '',
42
+ 'countryName' => '',
43
+ 'regionName' => '',
44
+ 'cityName' => '',
45
+ 'latitude' => '',
46
+ 'longitude' => '',
47
+ )
48
+ );*/
49
+
50
+ /**
51
+ * Constructer & Destructer
52
+ *
53
+ */
54
+ protected function __construct( $api_key = NULL ) {
55
+ if ( is_string( $api_key ) )
56
+ $this->template['api']['%API_KEY%'] = $api_key;
57
+ }
58
+
59
+ /**
60
+ * Build URL from template
61
+ *
62
+ */
63
+ protected static function build_url( $ip, $template ) {
64
+ $template['api']['%API_IP%'] = $ip;
65
+ return str_replace(
66
+ array_keys( $template['api'] ),
67
+ array_values( $template['api'] ),
68
+ $template['url']
69
+ );
70
+ }
71
+
72
+ /**
73
+ * Fetch service provider to get geolocation information
74
+ *
75
+ */
76
+ protected static function fetch_provider( $ip, $args, $template ) {
77
+
78
+ // check supported type of IP address
79
+ if ( ! ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) && ( $template['type'] & IP_GEO_BLOCK_API_TYPE_IPV4 ) ) &&
80
+ ! ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) && ( $template['type'] & IP_GEO_BLOCK_API_TYPE_IPV6 ) ) ) {
81
+ return FALSE;
82
+ }
83
+
84
+ // build query
85
+ $tmp = self::build_url( $ip, $template );
86
+
87
+ // http://codex.wordpress.org/Function_Reference/wp_remote_get
88
+ $res = @wp_remote_get( $tmp, $args ); // @since 2.7
89
+ if ( is_wp_error( $res ) )
90
+ return array( 'errorMessage' => $res->get_error_message() );
91
+ $tmp = wp_remote_retrieve_header( $res, 'content-type' );
92
+ $res = wp_remote_retrieve_body( $res );
93
+
94
+ // clear decoded data
95
+ $data = array();
96
+
97
+ // extract content type
98
+ // ex: "Content-type: text/plain; charset=utf-8"
99
+ if ( $tmp ) {
100
+ $tmp = explode( '/', $tmp, 2 );
101
+ $tmp = explode( ';', $tmp[1], 2 );
102
+ $tmp = trim( $tmp[0] );
103
+ }
104
+
105
+ switch ( $tmp ) {
106
+
107
+ // decode json
108
+ case 'json':
109
+ case 'html': // ipinfo.io, Xhanch
110
+ case 'plain': // geoPlugin
111
+ $data = json_decode( $res, TRUE ); // PHP 5 >= 5.2.0, PECL json >= 1.2.0
112
+ if ( NULL === $data ) // ipinfo.io (get_country)
113
+ $data[ $template['transform']['countryCode'] ] = trim( $res );
114
+ break;
115
+
116
+ // decode xml
117
+ case 'xml':
118
+ $tmp = '/\<(.+?)\>(?:\<\!\[CDATA\[)?([^\>]*?)(?:\]\]\>)?\<\/\\1\>/i';
119
+ if ( preg_match_all( $tmp, $res, $matches ) !== FALSE ) {
120
+ if ( is_array( $matches[1] ) && ! empty( $matches[1] ) ) {
121
+ foreach ( $matches[1] as $key => $val ) {
122
+ $data[ $val ] = $matches[2][ $key ];
123
+ }
124
+ }
125
+ }
126
+ break;
127
+
128
+ // unknown format
129
+ default:
130
+ return array( 'errorMessage' => "unsupported content type: $tmp" );
131
+ }
132
+
133
+ // transformation
134
+ $res = array();
135
+ foreach ( $template['transform'] as $key => $val ) {
136
+ if ( ! empty( $val ) && ! empty( $data[ $val ] ) )
137
+ $res[ $key ] = is_string( $data[ $val ] ) ?
138
+ esc_html( $data[ $val ] ) : $data[ $val ];
139
+ }
140
+
141
+ // if country code is '-' or 'UNDEFINED' then error.
142
+ if ( isset( $res['countryCode'] ) && is_string( $res['countryCode'] ) )
143
+ $res['countryCode'] = preg_match( '/^[A-Z]{2}/', $res['countryCode'], $matches ) ? $matches[0] : NULL;
144
+
145
+ return $res;
146
+ }
147
+
148
+ /**
149
+ * Get geolocation information from service provider
150
+ *
151
+ */
152
+ public function get_location( $ip, $args = array() ) {
153
+ return self::fetch_provider( $ip, $args, $this->template );
154
+ }
155
+
156
+ /**
157
+ * Get only country code
158
+ *
159
+ * Override this method if a provider supports this feature for quick response.
160
+ */
161
+ public function get_country( $ip, $args = array() ) {
162
+ $res = $this->get_location( $ip, $args );
163
+ return FALSE === $res ? FALSE : ( empty( $res['countryCode'] ) ? NULL : $res['countryCode'] );
164
+ }
165
+
166
+ /**
167
+ * Convert provider name to class name
168
+ *
169
+ */
170
+ public static function get_class_name( $provider ) {
171
+ $provider = 'IP_Geo_Block_API_' . preg_replace( '/[\W]/', '', $provider );
172
+ return class_exists( $provider ) ? $provider : NULL;
173
+ }
174
+
175
+ /**
176
+ * Get option key
177
+ *
178
+ */
179
+ public static function get_api_key( $provider, $options ) {
180
+ return empty( $options['providers'][ $provider ] ) ? NULL : $options['providers'][ $provider ];
181
+ }
182
+
183
+ /**
184
+ * Instance of inherited object
185
+ *
186
+ */
187
+ private static $instance = array();
188
+
189
+ public static function get_instance( $provider, $options ) {
190
+ if ( $name = self::get_class_name( $provider ) ) {
191
+ if ( empty( self::$instance[ $name ] ) )
192
+ return self::$instance[ $name ] = new $name( self::get_api_key( $provider, $options ) );
193
+ else
194
+ return self::$instance[ $name ];
195
+ }
196
+
197
+ return NULL;
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Class for freegeoip.net
203
+ *
204
+ * URL : http://freegeoip.net/
205
+ * Term of use :
206
+ * Licence fee : free (donationware)
207
+ * Rate limit : 10,000 queries per hour
208
+ * Sample URL : http://freegeoip.net/json/124.83.187.140
209
+ * Sample URL : http://freegeoip.net/xml/yahoo.co.jp
210
+ * Input type : IP address (IPv4, IPv6) / domain name
211
+ * Output type : json, jsonp, xml, csv
212
+ */
213
+ class IP_Geo_Block_API_freegeoipnet extends IP_Geo_Block_API {
214
+ protected $template = array(
215
+ 'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
216
+ 'url' => 'http://freegeoip.net/%API_FORMAT%/%API_IP%',
217
+ 'api' => array(
218
+ '%API_FORMAT%' => 'json',
219
+ ),
220
+ 'transform' => array(
221
+ 'countryCode' => 'country_code',
222
+ 'countryName' => 'country_name',
223
+ 'regionName' => 'region_name',
224
+ 'cityName' => 'city',
225
+ 'latitude' => 'latitude',
226
+ 'longitude' => 'longitude',
227
+ )
228
+ );
229
+ }
230
+
231
+ /**
232
+ * Class for ipinfo.io
233
+ *
234
+ * URL : http://ipinfo.io/
235
+ * Term of use : http://ipinfo.io/developers#terms
236
+ * Licence fee : free
237
+ * Rate limit :
238
+ * Sample URL : http://ipinfo.io/124.83.187.140/json
239
+ * Sample URL : http://ipinfo.io/124.83.187.140/country
240
+ * Input type : IP address (IPv4)
241
+ * Output type : json
242
+ */
243
+ class IP_Geo_Block_API_ipinfoio extends IP_Geo_Block_API {
244
+ protected $template = array(
245
+ 'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
246
+ 'url' => 'http://ipinfo.io/%API_IP%/%API_FORMAT%%API_OPTION%',
247
+ 'api' => array(
248
+ '%API_FORMAT%' => 'json',
249
+ '%API_OPTION%' => '',
250
+ ),
251
+ 'transform' => array(
252
+ 'countryCode' => 'country',
253
+ 'countryName' => 'country',
254
+ 'regionName' => 'region',
255
+ 'cityName' => 'city',
256
+ 'latitude' => 'loc',
257
+ 'longitude' => 'loc',
258
+ )
259
+ );
260
+
261
+ public function get_location( $ip, $args = array() ) {
262
+ $res = parent::get_location( $ip, $args );
263
+ if ( ! empty( $res ) && ! empty( $res['latitude'] ) ) {
264
+ $loc = explode( ',', $res['latitude'] );
265
+ $res['latitude' ] = $loc[0];
266
+ $res['longitude'] = $loc[1];
267
+ }
268
+ return $res;
269
+ }
270
+
271
+ public function get_country( $ip, $args = array() ) {
272
+ $this->template['api']['%API_FORMAT%'] = '';
273
+ $this->template['api']['%API_OPTION%'] = 'country';
274
+ return parent::get_country( $ip, $args );
275
+ }
276
+ }
277
+
278
+ /**
279
+ * Class for Nekudo
280
+ *
281
+ * URL : http://geoip.nekudo.com/
282
+ * Term of use : https://nekudo.com/blog/new-project-shiny-geoip
283
+ * Licence fee : free to use the API
284
+ * Rate limit : none
285
+ * Sample URL : http://geoip.nekudo.com/api/2a00:1210:fffe:200::1
286
+ * Input type : IP address (IPv4, IPv6)
287
+ * Output type : json
288
+ */
289
+ class IP_Geo_Block_API_Nekudo extends IP_Geo_Block_API {
290
+ protected $template = array(
291
+ 'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
292
+ 'url' => 'http://geoip.nekudo.com/api/%API_IP%',
293
+ 'api' => array(),
294
+ 'transform' => array(
295
+ 'countryCode' => 'country',
296
+ 'countryName' => 'country',
297
+ 'cityName' => 'city',
298
+ 'latitude' => 'location',
299
+ 'longitude' => 'location',
300
+ )
301
+ );
302
+
303
+ public function get_location( $ip, $args = array() ) {
304
+ $res = parent::get_location( $ip, $args );
305
+ if ( isset( $res['countryName'] ) && is_array( $res['countryName'] ) ) {
306
+ $res['countryCode'] = esc_html( $res['countryCode']['code'] );
307
+ $res['countryName'] = esc_html( $res['countryName']['name'] );
308
+ $res['latitude' ] = esc_html( $res['latitude' ]['latitude' ] );
309
+ $res['longitude' ] = esc_html( $res['longitude' ]['longitude'] );
310
+ return $res;
311
+ } else {
312
+ return array( 'errorMessage' => 'Not Found' ); // 404
313
+ }
314
+ }
315
+ }
316
+
317
+ /**
318
+ * Class for Xhanch
319
+ *
320
+ * URL : http://xhanch.com/xhanch-api-ip-get-detail/
321
+ * Term of use :
322
+ * Licence fee : free (donationware)
323
+ * Rate limit :
324
+ * Sample URL : http://api.xhanch.com/ip-get-detail.php?ip=124.83.187.140
325
+ * Sample URL : http://api.xhanch.com/ip-get-detail.php?ip=124.83.187.140&m=json
326
+ * Input type : IP address (IPv4)
327
+ * Output type : xml, json
328
+ */
329
+ class IP_Geo_Block_API_Xhanch extends IP_Geo_Block_API {
330
+ protected $template = array(
331
+ 'type' => IP_GEO_BLOCK_API_TYPE_IPV4,
332
+ 'url' => 'http://api.xhanch.com/ip-get-detail.php?ip=%API_IP%&m=%API_FORMAT%',
333
+ 'api' => array(
334
+ '%API_FORMAT%' => 'json',
335
+ ),
336
+ 'transform' => array(
337
+ 'countryCode' => 'country_code',
338
+ 'countryName' => 'country_name',
339
+ 'regionName' => 'region',
340
+ 'cityName' => 'city',
341
+ 'latitude' => 'latitude',
342
+ 'longitude' => 'longitude',
343
+ )
344
+ );
345
+ }
346
+
347
+ /**
348
+ * Class for GeoIPLookup.net
349
+ *
350
+ * URL : http://geoiplookup.net/
351
+ * Term of use : http://geoiplookup.net/terms-of-use.php
352
+ * Licence fee : free
353
+ * Rate limit : none
354
+ * Sample URL : http://api.geoiplookup.net/?query=2a00:1210:fffe:200::1
355
+ * Input type : IP address (IPv4, IPv6)
356
+ * Output type : xml
357
+ */
358
+ class IP_Geo_Block_API_GeoIPLookup extends IP_Geo_Block_API {
359
+ protected $template = array(
360
+ 'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
361
+ 'url' => 'http://api.geoiplookup.net/?query=%API_IP%',
362
+ 'api' => array(),
363
+ 'transform' => array(
364
+ 'countryCode' => 'countrycode',
365
+ 'countryName' => 'countryname',
366
+ 'regionName' => 'countryname',
367
+ 'cityName' => 'city',
368
+ 'latitude' => 'latitude',
369
+ 'longitude' => 'longitude',
370
+ )
371
+ );
372
+ }
373
+
374
+ /**
375
+ * Class for ip-api.com
376
+ *
377
+ * URL : http://ip-api.com/
378
+ * Term of use : http://ip-api.com/docs/#usage_limits
379
+ * Licence fee : free for non-commercial use
380
+ * Rate limit : 240 requests per minute
381
+ * Sample URL : http://ip-api.com/json/2a00:1210:fffe:200::1
382
+ * Sample URL : http://ip-api.com/xml/yahoo.co.jp
383
+ * Input type : IP address (IPv4, IPv6 with limited coverage) / domain name
384
+ * Output type : json, xml
385
+ */
386
+ class IP_Geo_Block_API_ipapicom extends IP_Geo_Block_API {
387
+ protected $template = array(
388
+ 'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
389
+ 'url' => 'http://ip-api.com/%API_FORMAT%/%API_IP%',
390
+ 'api' => array(
391
+ '%API_FORMAT%' => 'json',
392
+ ),
393
+ 'transform' => array(
394
+ 'errorMessage' => 'error',
395
+ 'countryCode' => 'countryCode',
396
+ 'countryName' => 'country',
397
+ 'regionName' => 'regionName',
398
+ 'cityName' => 'city',
399
+ 'latitude' => 'lat',
400
+ 'longitude' => 'lon',
401
+ )
402
+ );
403
+ }
404
+
405
+ /**
406
+ * Class for IPInfoDB
407
+ *
408
+ * URL : http://ipinfodb.com/
409
+ * Term of use : http://ipinfodb.com/ipinfodb_agreement.pdf
410
+ * Licence fee : free (need to regist to get API key)
411
+ * Rate limit : 2 queries/second for registered user
412
+ * Sample URL : http://api.ipinfodb.com/v3/ip-city/?key=...&format=xml&ip=124.83.187.140
413
+ * Sample URL : http://api.ipinfodb.com/v3/ip-country/?key=...&format=xml&ip=yahoo.co.jp
414
+ * Input type : IP address (IPv4, IPv6) / domain name
415
+ * Output type : json, xml
416
+ */
417
+ class IP_Geo_Block_API_IPInfoDB extends IP_Geo_Block_API {
418
+ protected $template = array(
419
+ 'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
420
+ 'url' => 'http://api.ipinfodb.com/v3/%API_OPTION%/?key=%API_KEY%&format=%API_FORMAT%&ip=%API_IP%',
421
+ 'api' => array(
422
+ '%API_FORMAT%' => 'xml',
423
+ '%API_OPTION%' => 'ip-city',
424
+ ),
425
+ 'transform' => array(
426
+ 'countryCode' => 'countryCode',
427
+ 'countryName' => 'countryName',
428
+ 'regionName' => 'regionName',
429
+ 'cityName' => 'cityName',
430
+ 'latitude' => 'latitude',
431
+ 'longitude' => 'longitude',
432
+ )
433
+ );
434
+
435
+ public function __construct( $api_key = NULL ) {
436
+ // sanitization
437
+ parent::__construct( preg_replace( '/\W/', '', $api_key ) );
438
+ }
439
+
440
+ public function get_country( $ip, $args = array() ) {
441
+ $this->api_template['%API_OPTION%'] = 'ip-country';
442
+ return parent::get_country( $ip, $args );
443
+ }
444
+ }
445
+
446
+ /**
447
+ * Class for Cache
448
+ *
449
+ * Input type : IP address (IPv4, IPv6)
450
+ * Output type : array
451
+ */
452
+ class IP_Geo_Block_API_Cache extends IP_Geo_Block_API {
453
+
454
+ // memory cache
455
+ protected static $memcache = array();
456
+
457
+ public static function update_cache( $hook, $validate, $settings ) {
458
+ $cache = self::get_cache( $ip = $validate['ip'] );
459
+
460
+ if ( $cache ) {
461
+ $fail = $cache['fail'] + ( empty( $validate['fail'] ) ? 0 : 1 );
462
+ $call = $cache['call'] + ( empty( $validate['fail'] ) ? 1 : 0 );
463
+ } else { // if new cache then reset these values
464
+ $fail = 0;
465
+ $call = 1;
466
+ }
467
+
468
+ // update elements
469
+ IP_Geo_Block_Logs::update_cache( $cache = array(
470
+ 'time' => $_SERVER['REQUEST_TIME'],
471
+ 'ip' => $ip,
472
+ 'hook' => $hook,
473
+ 'code' => $validate['code'],
474
+ 'auth' => $validate['auth'], // get_current_user_id() > 0
475
+ 'fail' => $fail, // $validate['auth'] ? 0 : $fail,
476
+ 'call' => $settings['save_statistics'] ? $call : 0,
477
+ 'host' => isset( $validate['host'] ) ? $validate['host'] : NULL,
478
+ ) );
479
+
480
+ return self::$memcache[ $ip ] = $cache;
481
+ }
482
+
483
+ public static function clear_cache() {
484
+ IP_Geo_Block_Logs::clear_cache();
485
+ self::$memcache = array();
486
+ }
487
+
488
+ public static function get_cache_all() {
489
+ return IP_Geo_Block_Logs::restore_cache();
490
+ }
491
+
492
+ public static function get_cache( $ip ) {
493
+ if ( ! empty( self::$memcache[ $ip ] ) )
494
+ return self::$memcache[ $ip ];
495
+ else
496
+ return self::$memcache[ $ip ] = IP_Geo_Block_Logs::search_cache( $ip );
497
+ }
498
+
499
+ public function get_location( $ip, $args = array() ) {
500
+ if ( $cache = self::get_cache( $ip ) )
501
+ return array( 'countryCode' => $cache['code'] );
502
+ else
503
+ return array( 'errorMessage' => 'not in the cache' );
504
+ }
505
+
506
+ public function get_country( $ip, $args = array() ) {
507
+ return ( $cache = self::get_cache( $ip ) ) ? $cache['code'] : NULL;
508
+ }
509
+ }
510
+
511
+ /**
512
+ * Provider support class
513
+ *
514
+ */
515
+ class IP_Geo_Block_Provider {
516
+
517
+ protected static $providers = array(
518
+
519
+ 'freegeoip.net' => array(
520
+ 'key' => NULL,
521
+ 'type' => 'IPv4, IPv6 / free',
522
+ 'link' => '<a rel="noreferrer" href="http://freegeoip.net/" title="freegeoip.net: FREE IP Geolocation Web Service">http://freegeoip.net/</a>&nbsp;(IPv4, IPv6 / free)',
523
+ ),
524
+
525
+ 'ipinfo.io' => array(
526
+ 'key' => NULL,
527
+ 'type' => 'IPv4, IPv6 / free',
528
+ 'link' => '<a rel="noreferrer" href="http://ipinfo.io/" title="ip address information including geolocation, hostname and network details">http://ipinfo.io/</a>&nbsp;(IPv4, IPv6 / free)',
529
+ ),
530
+
531
+ 'Nekudo' => array(
532
+ 'key' => NULL,
533
+ 'type' => 'IPv4, IPv6 / free',
534
+ 'link' => '<a rel="noreferrer" href="http://geoip.nekudo.com/" title="geoip.nekudo.com | Free IP to geolocation API">http://geoip.nekudo.com/</a>&nbsp;(IPv4, IPv6 / free)',
535
+ ),
536
+
537
+ 'Xhanch' => array(
538
+ 'key' => NULL,
539
+ 'type' => 'IPv4 / free',
540
+ 'link' => '<a rel="noreferrer" href="http://xhanch.com/xhanch-api-ip-get-detail/" title="Xhanch API &#8211; IP Get Detail | Xhanch Studio">http://xhanch.com/</a>&nbsp;(IPv4 / free)',
541
+ ),
542
+
543
+ 'GeoIPLookup' => array(
544
+ 'key' => NULL,
545
+ 'type' => 'IPv4, IPv6 / free',
546
+ 'link' => '<a rel="noreferrer" href="http://geoiplookup.net/" title="What Is My IP Address | GeoIP Lookup">GeoIPLookup.net</a>&nbsp;(IPv4, IPv6 / free)',
547
+ ),
548
+
549
+ 'ip-api.com' => array(
550
+ 'key' => FALSE,
551
+ 'type' => 'IPv4, IPv6 / free for non-commercial use',
552
+ 'link' => '<a rel="noreferrer" href="http://ip-api.com/" title="IP-API.com - Free Geolocation API">http://ip-api.com/</a>&nbsp;(IPv4, IPv6 / free for non-commercial use)',
553
+ ),
554
+
555
+ 'IPInfoDB' => array(
556
+ 'key' => '',
557
+ 'type' => 'IPv4, IPv6 / free for registered user',
558
+ 'link' => '<a rel="noreferrer" href="http://ipinfodb.com/" title="IPInfoDB | Free IP Address Geolocation Tools">http://ipinfodb.com/</a>&nbsp;(IPv4, IPv6 / free for registered user)',
559
+ ),
560
+ );
561
+
562
+ // Internal DB
563
+ protected static $internals = array(
564
+ 'Cache' => array(
565
+ 'key' => NULL,
566
+ 'type' => 'IPv4, IPv6',
567
+ 'link' => NULL,
568
+ ),
569
+ );
570
+
571
+ /**
572
+ * Register and get addon provider class information
573
+ *
574
+ */
575
+ public static function register_addon( $api ) {
576
+ self::$internals += $api;
577
+ }
578
+
579
+ public static function get_addons() {
580
+ $apis = array();
581
+
582
+ foreach ( self::$internals as $key => $val ) {
583
+ if ( 'Cache' !== $key )
584
+ $apis[] = $key;
585
+ }
586
+
587
+ return $apis;
588
+ }
589
+
590
+ /**
591
+ * Returns the pairs of provider name and API key
592
+ *
593
+ */
594
+ public static function get_providers( $key = 'key', $rand = FALSE, $cache = FALSE ) {
595
+ // add internal DB
596
+ $list = array();
597
+ foreach ( self::$internals as $provider => $tmp ) {
598
+ if ( 'Cache' !== $provider || $cache )
599
+ $list[ $provider ] = $tmp[ $key ];
600
+ }
601
+
602
+ $tmp = array_keys( self::$providers );
603
+
604
+ // randomize
605
+ if ( $rand )
606
+ shuffle( $tmp );
607
+
608
+ foreach ( $tmp as $name )
609
+ $list[ $name ] = self::$providers[ $name ][ $key ];
610
+
611
+ return $list;
612
+ }
613
+
614
+ /**
615
+ * Returns providers name list which are checked in settings
616
+ *
617
+ */
618
+ public static function get_valid_providers( $settings, $rand = TRUE, $cache = TRUE ) {
619
+ $list = array();
620
+
621
+ foreach ( self::get_providers( 'key', $rand, $cache ) as $provider => $key ) {
622
+ if ( ! empty( $settings[ $provider ] ) || (
623
+ ! isset( $settings[ $provider ] ) && NULL === $key ) ) {
624
+ $list[] = $provider;
625
+ }
626
+ }
627
+
628
+ return $list;
629
+ }
630
+
631
+ /**
632
+ * Check status of provider selection
633
+ *
634
+ */
635
+ public static function diag_providers( $settings = NULL ) {
636
+ if ( ! $settings ) {
637
+ $settings = IP_Geo_Block::get_option();
638
+ $settings = $settings['providers'];
639
+ }
640
+
641
+ $field = 0;
642
+ foreach ( self::get_providers( 'key' ) as $key => $val ) {
643
+ if ( ( NULL === $val && ! isset( $settings[ $key ] ) ) ||
644
+ ( FALSE === $val && ! empty( $settings[ $key ] ) ) ||
645
+ ( is_string( $val ) && ! empty( $settings[ $key ] ) ) ) {
646
+ $field++;
647
+ }
648
+ }
649
+
650
+ if ( 0 === $field )
651
+ return __( 'You need to select at least one IP geolocation service. Otherwise <strong>you\'ll be blocked</strong> after the cache expires.', 'ip-geo-block' );
652
+
653
+ return NULL;
654
+ }
655
+
656
+ }
657
+
658
+ /**
659
+ * Load additional plugins
660
+ *
661
+ */
662
+ if ( class_exists( 'IP_Geo_Block' ) ) {
663
+
664
+ // Get absolute path to the geo-location API
665
+ $dir = IP_Geo_Block::get_option();
666
+ $dir = IP_Geo_Block_Util::slashit(
667
+ apply_filters( IP_Geo_Block::PLUGIN_NAME . '-api-dir', dirname( $dir['api_dir'] ) )
668
+ ) . IP_Geo_Block::GEOAPI_NAME;
669
+
670
+ // If not exists then use bundled API
671
+ if ( ! is_dir( $dir ) )
672
+ $dir = IP_GEO_BLOCK_PATH . IP_Geo_Block::GEOAPI_NAME;
673
+
674
+ // Scan API directory
675
+ $dir = IP_Geo_Block_Util::slashit( $dir );
676
+ $plugins = is_dir( $dir ) ? scandir( $dir, 1 ) : FALSE; // SCANDIR_SORT_DESCENDING @since 5.4.0
677
+
678
+ // Load addons by heigher priority order
679
+ if ( FALSE !== $plugins ) {
680
+ $exclude = array( '.', '..' );
681
+ foreach ( $plugins as $plugin ) {
682
+ if ( ! in_array( $plugin, $exclude, TRUE ) && is_dir( $dir.$plugin ) ) {
683
+ @include $dir.$plugin.'/class-'.$plugin.'.php';
684
+ }
685
+ }
686
+ }
687
+
688
+ }
classes/class-ip-geo-block-cron.php ADDED
@@ -0,0 +1,350 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IP Geo Block - Cron Class
4
+ *
5
+ * @package IP_Geo_Block
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2016 tokkonopapa
10
+ */
11
+
12
+ class IP_Geo_Block_Cron {
13
+
14
+ /**
15
+ * Cron scheduler.
16
+ *
17
+ */
18
+ private static function schedule_cron_job( &$update, $db, $immediate = FALSE ) {
19
+ wp_clear_scheduled_hook( IP_Geo_Block::CRON_NAME, array( $immediate ) );
20
+
21
+ if ( $update['auto'] ) {
22
+ $now = time();
23
+ $cycle = DAY_IN_SECONDS * (int)$update['cycle'];
24
+
25
+ if ( FALSE === $immediate &&
26
+ $now - (int)$db['ipv4_last'] < $cycle &&
27
+ $now - (int)$db['ipv6_last'] < $cycle ) {
28
+ $update['retry'] = 0;
29
+ $next = max( (int)$db['ipv4_last'], (int)$db['ipv6_last'] ) +
30
+ $cycle + rand( DAY_IN_SECONDS, DAY_IN_SECONDS * 6 );
31
+ } else {
32
+ ++$update['retry'];
33
+ $next = $now + ( $immediate ? 0 : DAY_IN_SECONDS );
34
+ }
35
+
36
+ wp_schedule_single_event( $next, IP_Geo_Block::CRON_NAME, array( $immediate ) );
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Database auto downloader.
42
+ *
43
+ * This function is called when:
44
+ * 1. Plugin is activated
45
+ * 2. WP Cron is kicked
46
+ * under the following condition:
47
+ * A. Onece per site when this plugin is activated by network admin
48
+ * B. Multiple time for each blog when this plugin is individually activated
49
+ */
50
+ public static function exec_job( $immediate = FALSE ) {
51
+ $settings = IP_Geo_Block::get_option();
52
+ $args = IP_Geo_Block::get_request_headers( $settings );
53
+
54
+ // download database files (higher priority order)
55
+ foreach ( $providers = IP_Geo_Block_Provider::get_addons() as $provider ) {
56
+ if ( $geo = IP_Geo_Block_API::get_instance( $provider, $settings ) )
57
+ $res[ $provider ] = $geo->download( $settings[ $provider ], $args );
58
+ }
59
+
60
+ // re-schedule cron job
61
+ if ( ! empty( $providers ) )
62
+ self::schedule_cron_job( $settings['update'], $settings[ $providers[0] ], FALSE );
63
+
64
+ // update option settings
65
+ self::update_settings( $settings, array_merge( array( 'update' ), $providers ) );
66
+
67
+ // update matching rule immediately
68
+ if ( $immediate && FALSE !== get_transient( IP_Geo_Block::CRON_NAME ) ) {
69
+ add_filter( IP_Geo_Block::PLUGIN_NAME . '-ip-addr', array( __CLASS__, 'extract_ip' ) );
70
+
71
+ $validate = IP_Geo_Block::get_geolocation( NULL, $providers );
72
+ $validate = IP_Geo_Block::validate_country( NULL, $validate, $settings );
73
+
74
+ // if blocking may happen then disable validation
75
+ if ( -1 !== (int)$settings['matching_rule'] && 'passed' !== $validate['result'] &&
76
+ ( empty( $_SERVER['HTTP_X_REQUESTED_FROM'] ) || FALSE === strpos( $_SERVER['HTTP_X_REQUESTED_FROM'], 'InfiniteWP' ) ) ) {
77
+ $settings['matching_rule'] = -1;
78
+ }
79
+
80
+ // setup country code if it needs to be initialized
81
+ if ( -1 === (int)$settings['matching_rule'] && 'ZZ' !== $validate['code'] ) {
82
+ $settings['matching_rule'] = 0; // white list
83
+
84
+ if ( FALSE === strpos( $settings['white_list'], $validate['code'] ) )
85
+ $settings['white_list'] .= ( $settings['white_list'] ? ',' : '' ) . $validate['code'];
86
+ }
87
+
88
+ // update option settings
89
+ self::update_settings( $settings, array( 'matching_rule', 'white_list', 'black_list' ) );
90
+
91
+ // finished to update matching rule
92
+ set_transient( IP_Geo_Block::CRON_NAME, 'done', 5 * MINUTE_IN_SECONDS );
93
+ }
94
+
95
+ return isset( $res ) ? $res : NULL;
96
+ }
97
+
98
+ /**
99
+ * Update setting data according to the site type.
100
+ *
101
+ */
102
+ private static function update_settings( $src, $keys = array() ) {
103
+ if ( ! function_exists( 'is_plugin_active_for_network' ) )
104
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
105
+
106
+ // for multisite
107
+ if ( is_plugin_active_for_network( IP_GEO_BLOCK_BASE ) ) {
108
+ global $wpdb;
109
+ $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
110
+ $current_blog_id = get_current_blog_id();
111
+
112
+ foreach ( $blog_ids as $id ) {
113
+ switch_to_blog( $id );
114
+ $dst = IP_Geo_Block::get_option();
115
+
116
+ foreach ( $keys as $key ) {
117
+ $dst[ $key ] = $src[ $key ];
118
+ }
119
+
120
+ update_option( IP_Geo_Block::OPTION_NAME, $dst );
121
+ }
122
+
123
+ switch_to_blog( $current_blog_id );
124
+ }
125
+
126
+ // for single site
127
+ else {
128
+ update_option( IP_Geo_Block::OPTION_NAME, $src );
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Extract ip address from transient API.
134
+ *
135
+ */
136
+ public static function extract_ip() {
137
+ return filter_var(
138
+ $ip_adrs = get_transient( IP_Geo_Block::CRON_NAME ), FILTER_VALIDATE_IP
139
+ ) ? $ip_adrs : $_SERVER['REMOTE_ADDR'];
140
+ }
141
+
142
+ /**
143
+ * Kick off a cron job to download database immediately in background on activation.
144
+ *
145
+ */
146
+ public static function start_update_db( $settings ) {
147
+ if ( ! function_exists( 'is_plugin_active' ) )
148
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
149
+
150
+ // the status is still inactive when this plugin is activated on dashboard.
151
+ if ( ! is_plugin_active( IP_GEO_BLOCK_BASE ) ) {
152
+ set_transient( IP_Geo_Block::CRON_NAME, IP_Geo_Block::get_ip_address(), MINUTE_IN_SECONDS );
153
+ self::schedule_cron_job( $settings['update'], NULL, TRUE );
154
+ }
155
+ }
156
+
157
+ public static function stop_update_db() {
158
+ wp_clear_scheduled_hook( IP_Geo_Block::CRON_NAME, array( FALSE ) ); // @since 2.1.0
159
+ }
160
+
161
+ /**
162
+ * Kick off a cron job to garbage collection for IP address cache.
163
+ *
164
+ * Note: When the init action occurs in /wp-settings.php, wp_cron() runs.
165
+ */
166
+ public static function exec_cache_gc( $settings ) {
167
+ IP_Geo_Block_Logs::delete_expired_cache( $settings['cache_time'] );
168
+ self::stop_cache_gc();
169
+ self::start_cache_gc( $settings );
170
+ }
171
+
172
+ public static function start_cache_gc( $settings ) {
173
+ if ( ! wp_next_scheduled( IP_Geo_Block::CACHE_NAME ) )
174
+ wp_schedule_single_event( time() + $settings['cache_time_gc'], IP_Geo_Block::CACHE_NAME );
175
+ }
176
+
177
+ public static function stop_cache_gc() {
178
+ wp_clear_scheduled_hook( IP_Geo_Block::CACHE_NAME ); // @since 2.1.0
179
+ }
180
+
181
+ /**
182
+ * Download zip/gz file, uncompress and save it to specified file
183
+ *
184
+ * @param string $url URL of remote file to be downloaded.
185
+ * @param array $args request headers.
186
+ * @param string $filename full path to the downloaded file.
187
+ * @param int $modified time of last modified on the remote server.
188
+ * @return array status message.
189
+ */
190
+ public static function download_zip( $url, $args, $filename, $modified ) {
191
+ if ( ! function_exists( 'download_url' ) )
192
+ require_once ABSPATH . 'wp-admin/includes/file.php';
193
+
194
+ // if the name of src file is changed, then update the dst
195
+ if ( basename( $filename ) !== ( $base = pathinfo( $url, PATHINFO_FILENAME ) ) ) {
196
+ $filename = dirname( $filename ) . '/' . $base;
197
+ }
198
+
199
+ // check file
200
+ if ( ! file_exists( $filename ) )
201
+ $modified = 0;
202
+
203
+ // set 'If-Modified-Since' request header
204
+ $args += array(
205
+ 'headers' => array(
206
+ 'If-Modified-Since' => gmdate( DATE_RFC1123, (int)$modified ),
207
+ ),
208
+ );
209
+
210
+ // fetch file and get response code & message
211
+ $src = wp_remote_head( ( $url = esc_url_raw( $url ) ), $args );
212
+
213
+ if ( is_wp_error( $src ) )
214
+ return array(
215
+ 'code' => $src->get_error_code(),
216
+ 'message' => $src->get_error_message(),
217
+ );
218
+
219
+ $code = wp_remote_retrieve_response_code ( $src );
220
+ $mssg = wp_remote_retrieve_response_message( $src );
221
+ $data = wp_remote_retrieve_header( $src, 'last-modified' );
222
+ $modified = $data ? strtotime( $data ) : $modified;
223
+
224
+ if ( 304 == $code )
225
+ return array(
226
+ 'code' => $code,
227
+ 'message' => __( 'Your database file is up-to-date.', 'ip-geo-block' ),
228
+ 'filename' => $filename,
229
+ 'modified' => $modified,
230
+ );
231
+
232
+ elseif ( 200 != $code )
233
+ return array(
234
+ 'code' => $code,
235
+ 'message' => $code.' '.$mssg,
236
+ );
237
+
238
+ // downloaded and unzip
239
+ try {
240
+ // download file
241
+ $src = download_url( $url );
242
+
243
+ if ( is_wp_error( $src ) )
244
+ throw new Exception(
245
+ $src->get_error_code() . ' ' . $src->get_error_message()
246
+ );
247
+
248
+ // get extension
249
+ $args = strtolower( pathinfo( $url, PATHINFO_EXTENSION ) );
250
+
251
+ // unzip file
252
+ if ( 'gz' === $args && function_exists( 'gzopen' ) ) {
253
+ if ( FALSE === ( $gz = gzopen( $src, 'r' ) ) )
254
+ throw new Exception(
255
+ sprintf( __( 'Unable to read %s. Please check the permission.', 'ip-geo-block' ), $src )
256
+ );
257
+
258
+ if ( FALSE === ( $fp = @fopen( $filename, 'cb' ) ) )
259
+ throw new Exception(
260
+ sprintf( __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ), $filename )
261
+ );
262
+
263
+ if ( ! flock( $fp, LOCK_EX ) )
264
+ throw new Exception(
265
+ sprintf( __( 'Can\'t lock %s. Please try again after a while.', 'ip-geo-block' ), $filename )
266
+ );
267
+
268
+ ftruncate( $fp, 0 ); // truncate file
269
+
270
+ // same block size in wp-includes/class-http.php
271
+ while ( $data = gzread( $gz, 4096 ) ) {
272
+ fwrite( $fp, $data, strlen( $data ) );
273
+ }
274
+ }
275
+
276
+ elseif ( 'zip' === $args && class_exists( 'ZipArchive' ) ) {
277
+ // https://codex.wordpress.org/Function_Reference/unzip_file
278
+ WP_Filesystem();
279
+ $tmp = get_temp_dir(); // @since 2.5
280
+ $ret = unzip_file( $src, $tmp ); // @since 2.5
281
+
282
+ if ( is_wp_error( $ret ) )
283
+ throw new Exception(
284
+ $ret->get_error_code() . ' ' . $ret->get_error_message()
285
+ );
286
+
287
+ if ( FALSE === ( $gz = @fopen( $tmp .= basename( $filename ), 'r' ) ) )
288
+ throw new Exception(
289
+ sprintf( __( 'Unable to read %s. Please check the permission.', 'ip-geo-block' ), $src )
290
+ );
291
+
292
+ if ( FALSE === ( $fp = @fopen( $filename, 'cb' ) ) )
293
+ throw new Exception(
294
+ sprintf( __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ), $filename )
295
+ );
296
+
297
+ if ( ! flock( $fp, LOCK_EX ) )
298
+ throw new Exception(
299
+ sprintf( __( 'Can\'t lock %s. Please try again after a while.', 'ip-geo-block' ), $filename )
300
+ );
301
+
302
+ ftruncate( $fp, 0 ); // truncate file
303
+
304
+ // same block size in wp-includes/class-http.php
305
+ while ( $data = fread( $gz, 4096 ) ) {
306
+ fwrite( $fp, $data, strlen( $data ) );
307
+ }
308
+ }
309
+
310
+ if ( ! empty( $fp ) ) {
311
+ fflush( $fp ); // flush output before releasing the lock
312
+ flock ( $fp, LOCK_UN ); // release the lock
313
+ fclose( $fp );
314
+ }
315
+
316
+ ! empty( $gz ) and gzclose( $gz );
317
+ ! empty( $tmp ) && @is_file( $tmp ) and @unlink( $tmp );
318
+ ! is_wp_error( $src ) && @is_file( $src ) and @unlink( $src );
319
+ }
320
+
321
+ // error handler
322
+ catch ( Exception $e ) {
323
+ if ( ! empty( $fp ) ) {
324
+ fflush( $fp ); // flush output before releasing the lock
325
+ flock ( $fp, LOCK_UN ); // release the lock
326
+ fclose( $fp );
327
+ }
328
+
329
+ ! empty( $gz ) and gzclose( $gz );
330
+ ! empty( $tmp ) && @is_file( $tmp ) and @unlink( $tmp );
331
+ ! is_wp_error( $src ) && @is_file( $src ) and @unlink( $src );
332
+
333
+ return array(
334
+ 'code' => $e->getCode(),
335
+ 'message' => $e->getMessage(),
336
+ );
337
+ }
338
+
339
+ return array(
340
+ 'code' => $code,
341
+ 'message' => sprintf(
342
+ __( 'Last update: %s', 'ip-geo-block' ),
343
+ IP_Geo_Block_Util::localdate( $modified )
344
+ ),
345
+ 'filename' => $filename,
346
+ 'modified' => $modified,
347
+ );
348
+ }
349
+
350
+ }
classes/class-ip-geo-block-lkup.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IP Geo Block - DNS lookup
4
+ *
5
+ * @package IP_Geo_Block
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2016 tokkonopapa
10
+ */
11
+
12
+ class IP_Geo_Block_Lkup {
13
+
14
+ /**
15
+ * Converts IP address to in_addr representation
16
+ *
17
+ */
18
+ public static function inet_pton( $ip ) {
19
+ // available on Windows platforms after PHP 5.3.0
20
+ if ( function_exists( 'inet_pton' ) )
21
+ return inet_pton( $ip );
22
+
23
+ // http://stackoverflow.com/questions/14459041/inet-pton-replacement-function-for-php-5-2-17-in-windows
24
+ else {
25
+ // ipv4
26
+ if ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
27
+ if ( FALSE === strpos( $ip, ':' ) ) {
28
+ $ip = pack( 'N', ip2long( $ip ) );
29
+ } else {
30
+ $ip = explode( ':', $ip );
31
+ $ip = pack( 'N', ip2long( $ip[ count( $ip ) - 1 ] ) );
32
+ }
33
+ }
34
+
35
+ // ipv6
36
+ elseif ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
37
+ $ip = explode( ':', $ip );
38
+ $parts = 8 - count( $ip );
39
+ $res = '';
40
+ $replaced = 0;
41
+ foreach ( $ip as $seg ) {
42
+ if ( $seg != '' ) {
43
+ $res .= str_pad( $seg, 4, '0', STR_PAD_LEFT );
44
+ } elseif ( $replaced == 0 ) {
45
+ for ( $i = 0; $i <= $parts; $i++ )
46
+ $res .= '0000';
47
+ $replaced = 1;
48
+ } elseif ( $replaced == 1 ) {
49
+ $res .= '0000';
50
+ }
51
+ }
52
+ $ip = pack( 'H' . strlen( $res ), $res );
53
+ }
54
+ }
55
+
56
+ return $ip;
57
+ }
58
+
59
+ /**
60
+ * DNS lookup
61
+ *
62
+ */
63
+ public static function gethostbyaddr( $ip ) {
64
+ // available on Windows platforms after PHP 5.3.0
65
+ if ( function_exists( 'gethostbyaddr' ) )
66
+ $host = gethostbyaddr( $ip );
67
+
68
+ // if not available
69
+ if ( empty( $host ) ) {
70
+ if ( function_exists( 'dns_get_record' ) ) {
71
+ // generate in-addr.arpa notation
72
+ if ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
73
+ $ptr = implode( ".", array_reverse( explode( ".", $ip ) ) ) . ".in-addr.arpa";
74
+ }
75
+
76
+ elseif ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
77
+ $ptr = self::inet_pton( $ip );
78
+ $ptr = implode(".", array_reverse( str_split( bin2hex( $ptr ) ) ) ) . ".ip6.arpa";
79
+ }
80
+
81
+ if ( isset( $ptr ) and $ptr = @dns_get_record( $ptr, DNS_PTR ) ) {
82
+ $host = $ptr[0]['target'];
83
+ }
84
+ }
85
+ }
86
+
87
+ // For compatibility with versions before PHP 5.3.0
88
+ // on some operating systems, try the PEAR class Net_DNS
89
+ if ( empty( $host ) ) {
90
+ set_include_path( IP_GEO_BLOCK_PATH . 'includes' . PATH_SEPARATOR . get_include_path() );
91
+ require_once IP_GEO_BLOCK_PATH . 'includes/Net/DNS2.php';
92
+
93
+ // use google public dns
94
+ $r = new Net_DNS2_Resolver(
95
+ array( 'nameservers' => array( '8.8.8.8' ) )
96
+ );
97
+
98
+ try {
99
+ $result = $r->query( $ip, 'PTR' );
100
+ }
101
+ catch ( Net_DNS2_Exception $e ) {
102
+ $result = $e->getMessage();
103
+ }
104
+
105
+ if ( isset( $result->answer ) ) {
106
+ foreach ( $result->answer as $obj ) {
107
+ if ( 'PTR' === $obj->type ) {
108
+ $host = $obj->ptrdname;
109
+ break;
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ return isset( $host ) ? $host : $ip;
116
+ }
117
+
118
+ /**
119
+ * https://codex.wordpress.org/WordPress_Feeds
120
+ *
121
+ */
122
+ public static function is_feed( $request_uri ) {
123
+ return isset( $_GET['feed'] ) ?
124
+ ( preg_match( '!(?:comments-)?(?:feed|rss|rss2|rdf|atom)$!', $_GET['feed'] ) ? TRUE : FALSE ) :
125
+ ( preg_match( '!(?:comments/)?(?:feed|rss|rss2|rdf|atom)/?$!', $request_uri ) ? TRUE : FALSE );
126
+ }
127
+
128
+ }
classes/class-ip-geo-block-load.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IP Geo Block - Register all actions and filters for the plugin
4
+ *
5
+ * @package IP_Geo_Block
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2016 tokkonopapa
10
+ */
11
+
12
+ /**
13
+ * Register all actions and filters for the plugin.
14
+ *
15
+ * Maintain a list of all hooks that are registered throughout
16
+ * the plugin, and register them with the WordPress API. Call the
17
+ * run function to execute the list of actions and filters.
18
+ */
19
+ class IP_Geo_Block_Loader {
20
+
21
+ /**
22
+ * The array of actions registered with WordPress.
23
+ *
24
+ * @since 3.0.0
25
+ * @access protected
26
+ * @var array $actions The actions registered with WordPress to fire when the plugin loads.
27
+ */
28
+ protected $actions;
29
+
30
+ /**
31
+ * The array of filters registered with WordPress.
32
+ *
33
+ * @since 3.0.0
34
+ * @access protected
35
+ * @var array $filters The filters registered with WordPress to fire when the plugin loads.
36
+ */
37
+ protected $filters;
38
+
39
+ /**
40
+ * Initialize the collections used to maintain the actions and filters.
41
+ *
42
+ * @since 3.0.0
43
+ */
44
+ public function __construct() {
45
+
46
+ $this->actions = array();
47
+ $this->filters = array();
48
+
49
+ }
50
+
51
+ /**
52
+ * Add a new action to the collection to be registered with WordPress.
53
+ *
54
+ * @since 3.0.0
55
+ * @param string $hook The name of the WordPress action that is being registered.
56
+ * @param object $component A reference to the instance of the object on which the action is defined.
57
+ * @param string $callback The name of the function definition on the $component.
58
+ * @param int $priority Optional. he priority at which the function should be fired. Default is 10.
59
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
60
+ */
61
+ public function add_action( $hook, $callback, $priority = 10, $accepted_args = 1 ) {
62
+ $this->actions = $this->add( $this->actions, $hook, $callback, $priority, $accepted_args );
63
+ }
64
+
65
+ /**
66
+ * Add a new filter to the collection to be registered with WordPress.
67
+ *
68
+ * @since 3.0.0
69
+ * @param string $hook The name of the WordPress filter that is being registered.
70
+ * @param object $component A reference to the instance of the object on which the filter is defined.
71
+ * @param string $callback The name of the function definition on the $component.
72
+ * @param int $priority Optional. he priority at which the function should be fired. Default is 10.
73
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1
74
+ */
75
+ public function add_filter( $hook, $callback, $priority = 10, $accepted_args = 1 ) {
76
+ $this->filters = $this->add( $this->filters, $hook, $callback, $priority, $accepted_args );
77
+ }
78
+
79
+ public function apply_filters( $hook, $value ) {
80
+ $args = func_get_args();
81
+
82
+ foreach ( $this->filters as $index => $filter ) {
83
+ if ( $filter['hook'] === $hook ) {
84
+ $args[1] = $value;
85
+ $value = call_user_func_array(
86
+ $filter['callback'], array_slice( $args, 1, (int)$filter['accepted_args'] )
87
+ );
88
+ }
89
+ }
90
+
91
+ return $value;
92
+ }
93
+
94
+ /**
95
+ * A utility function that is used to register the actions and hooks into a single
96
+ * collection.
97
+ *
98
+ * @since 3.0.0
99
+ * @access private
100
+ * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
101
+ * @param string $hook The name of the WordPress filter that is being registered.
102
+ * @param object $component A reference to the instance of the object on which the filter is defined.
103
+ * @param string $callback The name of the function definition on the $component.
104
+ * @param int $priority The priority at which the function should be fired.
105
+ * @param int $accepted_args The number of arguments that should be passed to the $callback.
106
+ * @return array The collection of actions and filters registered with WordPress.
107
+ */
108
+ private function add( $hooks, $hook, $callback, $priority, $accepted_args ) {
109
+
110
+ $hooks[] = array(
111
+ 'hook' => $hook,
112
+ 'callback' => $callback,
113
+ 'priority' => $priority,
114
+ 'accepted_args' => $accepted_args
115
+ );
116
+
117
+ return $hooks;
118
+
119
+ }
120
+
121
+ /**
122
+ * Register the filters and actions with WordPress.
123
+ *
124
+ * @since 3.0.0
125
+ */
126
+ public function run() {
127
+
128
+ /**
129
+ * This part will be executed after loading this plugin.
130
+ * Register all the rest of the action and filter hooks.
131
+ */
132
+ if ( IP_Geo_Block_Util::may_be_logged_in() ) {
133
+ foreach ( $this->filters as $hook ) {
134
+ add_filter( $hook['hook'], $hook['callback'], $hook['priority'], $hook['accepted_args'] );
135
+ }
136
+
137
+ foreach ( $this->actions as $hook ) {
138
+ add_action( $hook['hook'], $hook['callback'], $hook['priority'], $hook['accepted_args'] );
139
+ }
140
+ }
141
+
142
+ /**
143
+ * This part will be executed at the very beginning of WordPress core.
144
+ * Execute callbacks that are specified by the component with 'init'.
145
+ */
146
+ else {
147
+ foreach ( $this->actions as $index => $hook ) {
148
+ if ( in_array( $hook['hook'], array( 'init', 'wp_loaded' ) ) ) {
149
+ // Execute callback directly
150
+ call_user_func( $hook['callback'], $hook['accepted_args'] );
151
+
152
+ // To avoid duplicated execution, delete this hook
153
+ unset( $this->actions[ $index ] );
154
+ }
155
+ }
156
+ }
157
+
158
+ }
159
+
160
+ }
classes/class-ip-geo-block-logs.php ADDED
@@ -0,0 +1,690 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IP Geo Block - Handling validation log
4
+ *
5
+ * @package IP_Geo_Block
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2016 tokkonopapa
10
+ */
11
+
12
+ // varchar can not be exceeded over 255 before MySQL-5.0.3.
13
+ define( 'IP_GEO_BLOCK_MAX_STR_LEN', 255 );
14
+ define( 'IP_GEO_BLOCK_MAX_TXT_LEN', 511 );
15
+
16
+ class IP_Geo_Block_Logs {
17
+
18
+ const TABLE_LOGS = 'ip_geo_block_logs';
19
+ const TABLE_STAT = 'ip_geo_block_stat';
20
+
21
+ // Initial statistics data
22
+ private static $default = array(
23
+ 'blocked' => 0,
24
+ 'unknown' => 0,
25
+ 'IPv4' => 0,
26
+ 'IPv6' => 0,
27
+ 'countries' => array(),
28
+ 'providers' => array(),
29
+ 'daystats' => array(),
30
+ );
31
+
32
+ /**
33
+ * Create
34
+ *
35
+ * @internal creating mixed storage engine may cause troubles with some plugins.
36
+ */
37
+ public static function create_tables() {
38
+ global $wpdb;
39
+ $result = TRUE;
40
+
41
+ // Default charset
42
+ $charset = 'utf8'; // MySQL 5.0+
43
+ if ( preg_match( '/CHARACTER SET (\w+)/i', $wpdb->get_charset_collate(), $table ) &&
44
+ FALSE !== strpos( $table[1], 'utf8' ) ) {
45
+ $charset = $table[1]; // ex) utf8mb4 MySQL 5.5+
46
+ }
47
+
48
+ // for logs
49
+ $table = $wpdb->prefix . self::TABLE_LOGS;
50
+ $result &= ( FALSE !== $wpdb->query( "CREATE TABLE IF NOT EXISTS `$table` (
51
+ `No` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
52
+ `time` int(10) unsigned NOT NULL DEFAULT 0,
53
+ `ip` varchar(40) NOT NULL,
54
+ `hook` varchar(8) NOT NULL,
55
+ `auth` int(10) unsigned NOT NULL DEFAULT 0,
56
+ `code` varchar(2) NOT NULL DEFAULT 'ZZ',
57
+ `result` varchar(8) NULL,
58
+ `method` varchar(" . IP_GEO_BLOCK_MAX_STR_LEN . ") NOT NULL,
59
+ `user_agent` varchar(" . IP_GEO_BLOCK_MAX_STR_LEN . ") NULL,
60
+ `headers` varchar(" . IP_GEO_BLOCK_MAX_TXT_LEN . ") NULL,
61
+ `data` text NULL,
62
+ PRIMARY KEY (`No`),
63
+ KEY `time` (`time`),
64
+ KEY `hook` (`hook`)
65
+ ) CHARACTER SET $charset"
66
+ ) ) or self::error( __LINE__ ); // utf8mb4 ENGINE=InnoDB or MyISAM
67
+
68
+ // for statistics
69
+ $table = $wpdb->prefix . self::TABLE_STAT;
70
+ $result &= ( FALSE !== $wpdb->query( "CREATE TABLE IF NOT EXISTS `$table` (
71
+ `No` tinyint(4) unsigned NOT NULL AUTO_INCREMENT,
72
+ `data` longtext NULL,
73
+ PRIMARY KEY (`No`)
74
+ ) CHARACTER SET $charset"
75
+ ) ) or self::error( __LINE__ ); // utf8mb4 ENGINE=InnoDB or MyISAM
76
+
77
+ // Create 1 record if not exists
78
+ $sql = $wpdb->prepare(
79
+ "INSERT INTO `$table` (`No`, `data`) VALUES (%d, %s)
80
+ ON DUPLICATE KEY UPDATE No = No", 1, serialize( self::$default )
81
+ ) and $wpdb->query( $sql );
82
+
83
+ // for IP address cache
84
+ $table = $wpdb->prefix . IP_Geo_Block::CACHE_NAME;
85
+ $result &= ( FALSE !== $wpdb->query( "CREATE TABLE IF NOT EXISTS `$table` (
86
+ `No` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
87
+ `time` int(10) unsigned NOT NULL DEFAULT 0,
88
+ `ip` varchar(40) NOT NULL,
89
+ `hook` varchar(8) NOT NULL,
90
+ `auth` int(10) unsigned NOT NULL DEFAULT 0,
91
+ `code` varchar(2) NOT NULL DEFAULT 'ZZ',
92
+ `fail` int(10) unsigned NOT NULL DEFAULT 0,
93
+ `call` int(10) unsigned NOT NULL DEFAULT 0,
94
+ `host` tinytext NOT NULL,
95
+ PRIMARY KEY (`No`),
96
+ UNIQUE KEY (`ip`)
97
+ ) CHARACTER SET $charset"
98
+ ) ) or self::error( __LINE__ ); // utf8mb4 ENGINE=InnoDB or MyISAM
99
+
100
+ return $result;
101
+ }
102
+
103
+ /**
104
+ * Search table by specific IP address
105
+ *
106
+ */
107
+ private static function search_table( $table, $ip, $type = FALSE ) {
108
+ global $wpdb;
109
+ $table = $wpdb->prefix . $table;
110
+
111
+ $sql = $wpdb->prepare(
112
+ "SELECT * FROM `$table` WHERE `ip` = '%s'", $ip
113
+ ) and $result = $wpdb->get_results( $sql, ARRAY_A ) or self::error( __LINE__ );
114
+
115
+ if ( ! $type )
116
+ return ! empty( $result[0] ) ? $result[0] : NULL; // for cache
117
+ else
118
+ return ! empty( $result ) ? $result : array(); // for logs
119
+ }
120
+
121
+ /**
122
+ * Delete
123
+ *
124
+ */
125
+ public static function delete_tables( $which = 'all' ) {
126
+ global $wpdb;
127
+ $tables = array( self::TABLE_LOGS, self::TABLE_STAT, IP_Geo_Block::CACHE_NAME );
128
+
129
+ foreach ( $tables as $table ) {
130
+ if ( 'all' === $which || $table === $which ) {
131
+ $table = $wpdb->prefix . $table;
132
+ $wpdb->query( "DROP TABLE IF EXISTS `$table`" ) or self::error( __LINE__ );
133
+ }
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Diagnose tables
139
+ *
140
+ */
141
+ public static function diag_tables() {
142
+ global $wpdb;
143
+ $tables = array( self::TABLE_LOGS, self::TABLE_STAT, IP_Geo_Block::CACHE_NAME );
144
+
145
+ foreach ( $tables as $table ) {
146
+ $table = $wpdb->prefix . $table;
147
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '$table'" ) !== $table ) {
148
+ return sprintf(
149
+ __( 'Creating a DB table %s had failed. Once de-activate this plugin, and then activate again.', 'ip-geo-block' ),
150
+ $table
151
+ );
152
+ }
153
+ }
154
+
155
+ return NULL;
156
+ }
157
+
158
+ /**
159
+ * Clear log data
160
+ *
161
+ */
162
+ public static function clear_logs( $hook = NULL ) {
163
+ global $wpdb;
164
+ $table = $wpdb->prefix . self::TABLE_LOGS;
165
+
166
+ if ( $hook )
167
+ $sql = $wpdb->prepare(
168
+ "DELETE FROM `$table` WHERE `hook` = '%s'", $hook
169
+ ) and $wpdb->query( $sql ) or self::error( __LINE__ );
170
+ else
171
+ $wpdb->query( "TRUNCATE TABLE `$table`" ) or self::error( __LINE__ );
172
+ }
173
+
174
+ /**
175
+ * Clear statistics data.
176
+ *
177
+ */
178
+ public static function clear_stat() {
179
+ self::record_stat( self::$default );
180
+ }
181
+
182
+ /**
183
+ * Restore statistics data.
184
+ *
185
+ */
186
+ public static function restore_stat( $default = FALSE ) {
187
+ global $wpdb;
188
+ $table = $wpdb->prefix . self::TABLE_STAT;
189
+
190
+ $data = $wpdb->get_results( "SELECT * FROM `$table`", ARRAY_A ) or self::error( __LINE__ );
191
+ return empty( $data ) ? ( $default ? self::$default : FALSE ) : unserialize( $data[0]['data'] );
192
+ }
193
+
194
+ /**
195
+ * Record statistics data.
196
+ *
197
+ */
198
+ public static function record_stat( $stat ) {
199
+ global $wpdb;
200
+ $table = $wpdb->prefix . self::TABLE_STAT;
201
+
202
+ if ( ! is_array( $stat ) ) {
203
+ $stat = self::$default;
204
+ }
205
+
206
+ $sql = $wpdb->prepare(
207
+ "UPDATE `$table` SET `data` = '%s'", serialize( $stat )
208
+ // "REPLACE INTO `$table` (`No`, `data`) VALUES (%d, %s)", 1, serialize( $stat )
209
+ ) and $wpdb->query( $sql ) or self::error( __LINE__ );
210
+ }
211
+
212
+ /**
213
+ * Limit the number of rows to send to the user agent according the processing time [msec]
214
+ *
215
+ */
216
+ public static function limit_rows( $time ) {
217
+ $options = IP_Geo_Block::get_option();
218
+ return (int)( $options['validation']['maxlogs'] / ((int)$time < 50 ? 1 : 2) );
219
+ }
220
+
221
+ /**
222
+ * Validate string whether utf8
223
+ *
224
+ * @see wp_check_invalid_utf8() in wp-includes/formatting.php
225
+ * @link https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php
226
+ */
227
+ private static function validate_utf8( $str ) {
228
+ $str = (string) $str;
229
+ if ( 0 === strlen( $str ) )
230
+ return '';
231
+
232
+ // Store the site charset as a static to avoid multiple calls to get_option()
233
+ static $is_utf8 = NULL;
234
+ if ( $is_utf8 === NULL )
235
+ $is_utf8 = array_key_exists(
236
+ get_option( 'blog_charset' ),
237
+ array( 'utf8' => NULL, 'utf-8' => NULL, 'UTF8' => NULL, 'UTF-8' => NULL )
238
+ );
239
+
240
+ // handle utf8 only
241
+ if ( ! $is_utf8 )
242
+ return '…';
243
+
244
+ // Check support for utf8 in the installed PCRE library
245
+ static $utf8_pcre = NULL;
246
+ if ( $utf8_pcre === NULL )
247
+ $utf8_pcre = preg_match( '/^./u', 'a' );
248
+
249
+ // if no support then reject $str for safety
250
+ if ( ! $utf8_pcre )
251
+ return '…';
252
+
253
+ // preg_match fails when it encounters invalid UTF8 in $str
254
+ if ( 1 === preg_match( '/^./us', $str ) ) {
255
+ // remove utf8mb4 4 bytes character
256
+ // @see strip_invalid_text() in wp-includes/wp-db.php
257
+ $regex = '/(?:\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})/';
258
+ return preg_replace( $regex, '', $str );
259
+ }
260
+
261
+ return '…';
262
+ }
263
+
264
+ /**
265
+ * Truncate string as utf8
266
+ *
267
+ * @see http://jetpack.wp-a2z.org/oik_api/mbstring_binary_safe_encoding/
268
+ * @link https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php
269
+ * @link https://core.trac.wordpress.org/browser/trunk/src/wp-includes/functions.php
270
+ */
271
+ private static function truncate_utf8( $str, $regexp = NULL, $replace = '', $len = IP_GEO_BLOCK_MAX_STR_LEN ) {
272
+ // remove unnecessary characters
273
+ $str = preg_replace( '/[\x00-\x1f\x7f]/', '', $str );
274
+ if ( $regexp )
275
+ $str = preg_replace( $regexp, $replace, $str );
276
+
277
+ // limit the length of the string
278
+ if ( function_exists( 'mb_strcut' ) ) {
279
+ mbstring_binary_safe_encoding(); // @since 3.7.0
280
+ if ( strlen( $str ) > $len )
281
+ $str = mb_strcut( $str, 0, $len ) . '…';
282
+ reset_mbstring_encoding(); // @since 3.7.0
283
+ }
284
+
285
+ else { // https://core.trac.wordpress.org/ticket/25259
286
+ mbstring_binary_safe_encoding(); // @since 3.7.0
287
+ $original = strlen( $str );
288
+ $str = substr( $str, 0, $len );
289
+ $length = strlen( $str );
290
+ reset_mbstring_encoding(); // @since 3.7.0
291
+
292
+ if ( $length !== $original ) {
293
+ // bit pattern from seems_utf8() in wp-includes/formatting.php
294
+ static $code = array(
295
+ array( 0x80, 0x00 ), // 1byte 0bbbbbbb
296
+ array( 0xE0, 0xC0 ), // 2bytes 110bbbbb
297
+ array( 0xF0, 0xE0 ), // 3bytes 1110bbbb
298
+ array( 0xF8, 0xF0 ), // 4bytes 11110bbb
299
+ array( 0xFC, 0xF8 ), // 5bytes 111110bb
300
+ array( 0xFE, 0xFC ), // 6bytes 1111110b
301
+ );
302
+
303
+ // truncate extra characters
304
+ $len = min( $length, 6 );
305
+ for ( $i = 0; $i < $len; $i++ ) {
306
+ $c = ord( $str[$length-1 - $i] );
307
+ for ( $j = $i; $j < 6; $j++ ) {
308
+ if ( ( $c & $code[$j][0] ) == $code[$j][1] ) {
309
+ mbstring_binary_safe_encoding(); // @since 3.7.0
310
+ $str = substr( $str, 0, $length - (int)($j > 0) - $i );
311
+ reset_mbstring_encoding(); // @since 3.7.0
312
+
313
+ // validate whole characters
314
+ $str = self::validate_utf8( $str );
315
+ return '…' !== $str ? $str . '…' : '…';
316
+ }
317
+ }
318
+ }
319
+
320
+ // $str may not fit utf8
321
+ return '…';
322
+ }
323
+ }
324
+
325
+ // validate whole characters
326
+ return self::validate_utf8( $str );
327
+ }
328
+
329
+ /**
330
+ * Get data
331
+ *
332
+ * These data must be sanitized before rendering
333
+ */
334
+ private static function get_user_agent() {
335
+ return isset( $_SERVER['HTTP_USER_AGENT'] ) ?
336
+ self::truncate_utf8( $_SERVER['HTTP_USER_AGENT'] ) : '';
337
+ }
338
+
339
+ private static function get_http_headers() {
340
+ $exclusions = array(
341
+ 'HTTP_ACCEPT' => TRUE,
342
+ 'HTTP_ACCEPT_CHARSET' => TRUE,
343
+ 'HTTP_ACCEPT_ENCODING' => TRUE,
344
+ 'HTTP_ACCEPT_LANGUAGE' => TRUE,
345
+ 'HTTP_CACHE_CONTROL' => TRUE,
346
+ 'HTTP_CONNECTION' => TRUE,
347
+ 'HTTP_COOKIE' => TRUE,
348
+ 'HTTP_HOST' => TRUE,
349
+ 'HTTP_PRAGMA' => TRUE,
350
+ 'HTTP_USER_AGENT' => TRUE,
351
+ );
352
+
353
+ // select headers to hold in the logs
354
+ $headers = array();
355
+ foreach ( array_keys( $_SERVER ) as $key ) {
356
+ if ( 'HTTP_' === substr( $key, 0, 5 ) && empty( $exclusions[ $key ] ) )
357
+ $headers[] = $key . '=' . $_SERVER[ $key ];
358
+ }
359
+
360
+ return self::truncate_utf8(
361
+ implode( ',', $headers ), NULL, '', IP_GEO_BLOCK_MAX_STR_LEN
362
+ );
363
+ }
364
+
365
+ private static function get_post_data( $hook, $validate, $settings ) {
366
+ // condition of masking password
367
+ $mask_pwd = ( 'passed' === $validate['result'] );
368
+
369
+ // XML-RPC
370
+ if ( 'xmlrpc' === $hook ) {
371
+ $posts = self::truncate_utf8(
372
+ file_get_contents( 'php://input' ), '!\s*([<>])\s*!', '$1', IP_GEO_BLOCK_MAX_STR_LEN
373
+ );
374
+
375
+ // mask the password
376
+ if ( $mask_pwd &&
377
+ preg_match_all( '/<string>(\S*?)<\/string>/', $posts, $matches ) >= 2 &&
378
+ strpos( $matches[1][1], home_url() ) !== 0 ) { // except pingback
379
+ $posts = str_replace( $matches[1][1], '***', $posts );
380
+ }
381
+ /*if ( FALSE !== ( $xml = @simplexml_load_string( $HTTP_RAW_POST_DATA ) ) ) {
382
+ // mask the password
383
+ if ( $mask_pwd && 'wp.' === substr( $xml->methodName, 0, 3 ) ) {
384
+ $xml->params->param[1]->value->string = '***';
385
+ }
386
+ $posts = self::truncate_utf8( wp_json_encode( $xml ), '/["\\\\]/' );
387
+ } else {
388
+ $posts = 'xml parse error: malformed xml';
389
+ }*/
390
+ }
391
+
392
+ // post data
393
+ else {
394
+ $keys = array_fill_keys( array_keys( $_POST ), NULL );
395
+ foreach ( explode( ',', $settings['validation']['postkey'] ) as $key ) {
396
+ if ( array_key_exists( $key, $_POST ) ) {
397
+ // mask the password
398
+ $keys[ $key ] = ( 'pwd' === $key && $mask_pwd ) ? '***' : $_POST[ $key ];
399
+ }
400
+ }
401
+
402
+ // Join array elements
403
+ $posts = array();
404
+ foreach ( $keys as $key => $val )
405
+ $posts[] = $val ? $key.'='.$val : $key;
406
+
407
+ $posts = self::truncate_utf8(
408
+ implode( ',', $posts ), '/\s+/', ' ', IP_GEO_BLOCK_MAX_STR_LEN
409
+ );
410
+ }
411
+
412
+ return $posts;
413
+ }
414
+
415
+ /**
416
+ * Backup the validation log to text files
417
+ *
418
+ * Note: $path should not be within the public_html.
419
+ */
420
+ private static function backup_logs( $hook, $validate, $method, $agent, $heads, $posts, $path ) {
421
+ // $path should be absolute path to the directory
422
+ if ( validate_file( $path ) !== 0 )
423
+ return;
424
+
425
+ $path = IP_Geo_Block_Util::slashit( $path ) .
426
+ IP_Geo_Block::PLUGIN_NAME . date('-Y-m') . '.log';
427
+
428
+ if ( ( $fp = @fopen( $path, 'ab' ) ) === FALSE )
429
+ return;
430
+
431
+ fprintf( $fp, "%d,%s,%s,%d,%s,%s,%s,%s,%s,%s\n",
432
+ $_SERVER['REQUEST_TIME'],
433
+ $validate['ip'],
434
+ $hook,
435
+ $validate['auth'],
436
+ $validate['code'],
437
+ $validate['result'],
438
+ $method,
439
+ str_replace( ',', '‚', $agent ), // &#044; --> &#130;
440
+ str_replace( ',', '‚', $heads ), // &#044; --> &#130;
441
+ str_replace( ',', '‚', $posts ) // &#044; --> &#130;
442
+ );
443
+
444
+ fclose( $fp );
445
+ }
446
+
447
+ /**
448
+ * Record the validation log
449
+ *
450
+ * This function record the user agent string and post data.
451
+ * The security policy for these data is as follows.
452
+ *
453
+ * 1. Record only utf8 under the condition that the site charset is utf8
454
+ * 2. Record by limiting the length of the string
455
+ * 3. Mask the password if it is authenticated
456
+ *
457
+ * @param string $hook type of log name
458
+ * @param array $validate validation results
459
+ * @param array $settings option settings
460
+ */
461
+ public static function record_logs( $hook, $validate, $settings ) {
462
+ // get data
463
+ $agent = self::get_user_agent();
464
+ $heads = self::get_http_headers();
465
+ $posts = self::get_post_data( $hook, $validate, $settings );
466
+ $method = $_SERVER['REQUEST_METHOD'] . '[' . $_SERVER['SERVER_PORT'] . ']:' . $_SERVER['REQUEST_URI'];
467
+
468
+ // anonymize ip address
469
+ if ( ! empty( $settings['anonymize'] ) )
470
+ $validate['ip'] = preg_replace( '/\d{1,3}$/', '***', $validate['ip'] );
471
+
472
+ // limit the maximum number of rows
473
+ $rows = (int)$settings['validation']['maxlogs'];
474
+
475
+ // count the number of rows for each hook
476
+ global $wpdb;
477
+ $table = $wpdb->prefix . self::TABLE_LOGS;
478
+ $sql = $wpdb->prepare(
479
+ "SELECT count(*) FROM `$table` WHERE `hook` = '%s'", $hook
480
+ ) and $count = (int)$wpdb->get_var( $sql );
481
+
482
+ if ( isset( $count ) && $count >= $rows ) {
483
+ // Can't start transaction on the assumption that the storage engine is innoDB.
484
+ // So there are some cases where logs are excessively deleted.
485
+ $sql = $wpdb->prepare(
486
+ "DELETE FROM `$table` WHERE `hook` = '%s' ORDER BY `No` ASC LIMIT %d",
487
+ $hook, $count - $rows + 1
488
+ ) and $wpdb->query( $sql ) or self::error( __LINE__ );
489
+ }
490
+
491
+ // insert into DB
492
+ $sql = $wpdb->prepare(
493
+ "INSERT INTO `$table`
494
+ (`time`, `ip`, `hook`, `auth`, `code`, `result`, `method`, `user_agent`, `headers`, `data`)
495
+ VALUES (%d, %s, %s, %d, %s, %s, %s, %s, %s, %s)",
496
+ $_SERVER['REQUEST_TIME'],
497
+ $validate['ip'],
498
+ $hook,
499
+ $validate['auth'],
500
+ $validate['code'],
501
+ $validate['result'],
502
+ $method,
503
+ $agent,
504
+ $heads,
505
+ $posts
506
+ ) and $wpdb->query( $sql ) or self::error( __LINE__ );
507
+
508
+ // backup logs to text files
509
+ if ( $dir = apply_filters(
510
+ IP_Geo_Block::PLUGIN_NAME . '-backup-dir',
511
+ $settings['validation']['backup'], $hook
512
+ ) ) {
513
+ self::backup_logs(
514
+ $hook, $validate, $method, $agent, $heads, $posts, $dir
515
+ );
516
+ }
517
+ }
518
+
519
+ /**
520
+ * Restore the validation log
521
+ *
522
+ * @param string $hook type of log name
523
+ * @return array log data
524
+ */
525
+ public static function restore_logs( $hook = NULL ) {
526
+ global $wpdb;
527
+ $table = $wpdb->prefix . self::TABLE_LOGS;
528
+
529
+ $sql = "SELECT `hook`, `time`, `ip`, `code`, `result`, `method`, `user_agent`, `headers`, `data` FROM `$table`";
530
+
531
+ if ( ! $hook )
532
+ $sql .= " ORDER BY `hook`, `No` DESC";
533
+ else
534
+ $sql .= $wpdb->prepare( " WHERE `hook` = '%s' ORDER BY `No` DESC", $hook );
535
+
536
+ return $sql ? $wpdb->get_results( $sql, ARRAY_N ) : array();
537
+ }
538
+
539
+ /**
540
+ * Search logs by specific IP address
541
+ *
542
+ */
543
+ public static function search_logs( $ip ) {
544
+ return self::search_table( self::TABLE_LOGS, $ip, TRUE );
545
+ }
546
+
547
+ /**
548
+ * Update statistics.
549
+ *
550
+ */
551
+ public static function update_stat( $hook, $validate, $settings ) {
552
+ // Restore statistics.
553
+ if ( $stat = self::restore_stat() ) {
554
+
555
+ $provider = isset( $validate['provider'] ) ? $validate['provider'] : 'ZZ';
556
+ if ( empty( $stat['providers'][ $provider ] ) )
557
+ $stat['providers'][ $provider ] = array( 'count' => 0, 'time' => 0.0 );
558
+
559
+ $stat['providers'][ $provider ]['count']++; // undefined in auth_fail()
560
+ $stat['providers'][ $provider ]['time'] += (float)@$validate['time'];
561
+
562
+ if ( 'passed' !== $validate['result'] ) {
563
+ // Blocked by type of IP address
564
+ if ( filter_var( $validate['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) )
565
+ $stat['IPv4']++;
566
+ elseif ( filter_var( $validate['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) )
567
+ $stat['IPv6']++;
568
+
569
+ @$stat['blocked' ]++;
570
+ @$stat['countries'][ $validate['code'] ]++;
571
+ @$stat['daystats' ][ mktime( 0, 0, 0 ) ][ $hook ]++;
572
+ }
573
+
574
+ if ( count( $stat['daystats'] ) > max( 30, min( 365, (int)@$settings['validation']['recdays'] ) ) ) {
575
+ reset( $stat['daystats'] );
576
+ unset( $stat['daystats'][ key( $stat['daystats'] ) ] );
577
+ }
578
+
579
+ // Record statistics.
580
+ self::record_stat( $stat );
581
+ }
582
+ }
583
+
584
+ /**
585
+ * Clear IP address cache.
586
+ *
587
+ */
588
+ public static function clear_cache() {
589
+ global $wpdb;
590
+ $table = $wpdb->prefix . IP_Geo_Block::CACHE_NAME;
591
+ $wpdb->query( "TRUNCATE TABLE `$table`" ) or self::error( __LINE__ );
592
+ }
593
+
594
+ /**
595
+ * Search cache by specific IP address
596
+ *
597
+ */
598
+ public static function search_cache( $ip ) {
599
+ return self::search_table( IP_Geo_Block::CACHE_NAME, $ip );
600
+ }
601
+
602
+ /**
603
+ * Restore cache
604
+ *
605
+ */
606
+ public static function restore_cache() {
607
+ global $wpdb;
608
+ $table = $wpdb->prefix . IP_Geo_Block::CACHE_NAME;
609
+ $result = $wpdb->get_results( "SELECT * FROM `$table`", ARRAY_A ) or self::error( __LINE__ );
610
+
611
+ // transform DB to cache format
612
+ $cache = $hash = array();
613
+ foreach ( $result as $key => $val ) {
614
+ $ip = $val['ip'];
615
+ unset( $val['ip'] );
616
+ $cache[ $ip ] = $val;
617
+ }
618
+
619
+ // sort by 'time'
620
+ foreach ( $cache as $key => $val )
621
+ $hash[ $key ] = $val['time'];
622
+
623
+ array_multisort( $hash, SORT_DESC, $cache );
624
+
625
+ return $cache;
626
+ }
627
+
628
+ /**
629
+ * Update cache
630
+ *
631
+ */
632
+ public static function update_cache( $cache ) {
633
+ global $wpdb;
634
+ $table = $wpdb->prefix . IP_Geo_Block::CACHE_NAME;
635
+
636
+ $sql = $wpdb->prepare(
637
+ "INSERT INTO `$table`
638
+ (`time`, `ip`, `hook`, `auth`, `code`, `fail`, `call`, `host`)
639
+ VALUES (%d, %s, %s, %d, %s, %d, %d, %s)
640
+ ON DUPLICATE KEY UPDATE
641
+ `time` = VALUES(`time`),
642
+ `hook` = VALUES(`hook`),
643
+ `auth` = VALUES(`auth`),
644
+ `code` = VALUES(`code`),
645
+ `fail` = VALUES(`fail`),
646
+ `call` = VALUES(`call`),
647
+ `host` = VALUES(`host`)",
648
+ $cache['time'],
649
+ $cache['ip' ],
650
+ $cache['hook'],
651
+ $cache['auth'],
652
+ $cache['code'],
653
+ $cache['fail'],
654
+ $cache['call'],
655
+ $cache['host']
656
+ ) and $wpdb->query( $sql ) or self::error( __LINE__ );
657
+ }
658
+
659
+ /**
660
+ * Delete expired cache
661
+ *
662
+ */
663
+ public static function delete_expired_cache( $cache_time ) {
664
+ global $wpdb;
665
+ $table = $wpdb->prefix . IP_Geo_Block::CACHE_NAME;
666
+
667
+ $sql = $wpdb->prepare(
668
+ "DELETE FROM `$table` WHERE `time` < %d",
669
+ $_SERVER['REQUEST_TIME'] - $cache_time
670
+ ) and $result = $wpdb->query( $sql ) or self::error( __LINE__ );
671
+
672
+ return $result;
673
+ }
674
+
675
+ /**
676
+ * SQL Error handling
677
+ *
678
+ */
679
+ private static function error( $line ) {
680
+ global $wpdb;
681
+ if ( $wpdb->last_error ) {
682
+ if ( class_exists( 'IP_Geo_Block_Admin' ) )
683
+ IP_Geo_Block_Admin::add_admin_notice( 'error', __FILE__ . ' (' . $line . ') ' . $wpdb->last_error );
684
+
685
+ if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG )
686
+ error_log( __FILE__ . ' (' . $line . ') ' . $wpdb->last_error );
687
+ }
688
+ }
689
+
690
+ }
classes/class-ip-geo-block-opts.php ADDED
@@ -0,0 +1,425 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IP Geo Block - Options
4
+ *
5
+ * @package IP_Geo_Block
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2016 tokkonopapa
10
+ */
11
+
12
+ class IP_Geo_Block_Opts {
13
+
14
+ /**
15
+ * Default values of option table to be cached into options database table.
16
+ *
17
+ */
18
+ private static $option_table = array(
19
+ 'version' => '3.0.0', // Version of this table (not package)
20
+ // since version 1.0
21
+ 'providers' => array(), // List of providers and API keys
22
+ 'comment' => array( // Message on the comment form
23
+ 'pos' => 0, // Position (0:none, 1:top, 2:bottom)
24
+ 'msg' => NULL, // Message text on comment form
25
+ ),
26
+ 'matching_rule' => -1, // -1:neither, 0:white list, 1:black list
27
+ 'white_list' => NULL, // Comma separeted country code
28
+ 'black_list' => 'ZZ', // Comma separeted country code
29
+ 'timeout' => 5, // Timeout in second
30
+ 'response_code' => 403, // Response code
31
+ 'save_statistics' => TRUE, // Record validation statistics
32
+ 'clean_uninstall' => FALSE, // Remove all savings from DB
33
+ // since version 1.1
34
+ 'cache_hold' => 10, // Max entries in cache
35
+ 'cache_time' => HOUR_IN_SECONDS, // @since 3.5
36
+ // since version 3.0.0
37
+ 'cache_time_gc' => 900, // Cache garbage collection time
38
+ // since version 1.2, 1.3
39
+ 'login_fails' => 5, // Limited number of login attempts
40
+ 'validation' => array( // Action hook for validation
41
+ 'comment' => FALSE, // Validate on comment post
42
+ 'login' => 1, // Validate on login
43
+ 'admin' => 1, // Validate on admin (1:country 2:ZEP)
44
+ 'ajax' => 0, // Validate on ajax/post (1:country 2:ZEP)
45
+ 'xmlrpc' => 1, // Validate on xmlrpc (1:country 2:close)
46
+ 'proxy' => NULL, // $_SERVER variables for IPs
47
+ 'reclogs' => 1, // 1:blocked 2:passed 3:unauth 4:auth 5:all
48
+ 'postkey' => NULL, // Keys in $_POST
49
+ // since version 1.3.1
50
+ 'maxlogs' => 100, // Max number of rows of log
51
+ 'backup' => NULL, // Absolute path to directory for backup logs
52
+ // since version 2.1.0
53
+ 'plugins' => 0, // Validate on wp-content/plugins
54
+ 'themes' => 0, // Validate on wp-content/themes
55
+ // since version 2.2.9
56
+ 'timing' => 0, // 0:init, 1:mu-plugins, 2:drop-in
57
+ 'recdays' => 30, // Number of days for recording logs
58
+ // since version 3.0.0
59
+ 'includes' => 3, // for wp-includes/
60
+ 'uploads' => 3, // for UPLOADS/uploads
61
+ 'languages' => 3, // for WP_CONTENT_DIR/language
62
+ 'public' => 0, // Validate on public facing pages
63
+ ),
64
+ 'update' => array( // Updating IP address DB
65
+ 'auto' => TRUE, // Auto updating of DB file
66
+ 'retry' => 0, // Number of retry to download
67
+ 'cycle' => 30, // Updating cycle (days)
68
+ ),
69
+ // since version 2.0.8
70
+ 'priority' => 0, // Action priority for WP-ZEP
71
+ // since version 2.2.0
72
+ 'anonymize' => FALSE, // Anonymize IP address to hide privacy
73
+ 'signature' => '../,/wp-config.php,/passwd', // malicious signature
74
+ 'extra_ips' => array( // Additional IP validation
75
+ 'white_list' => NULL, // White list of IP addresses
76
+ 'black_list' => NULL, // Black list of IP addresses
77
+ ),
78
+ 'rewrite' => array( // Apply rewrite rule
79
+ 'plugins' => FALSE, // for wp-content/plugins
80
+ 'themes' => FALSE, // for wp-content/themes
81
+ // since version 3.0.0
82
+ 'public' => FALSE, // for public facing pages
83
+ 'includes' => FALSE, // for wp-includes/
84
+ 'uploads' => FALSE, // for UPLOADS/uploads
85
+ 'languages' => FALSE, // for wp-content/language
86
+ ),
87
+ 'Maxmind' => array( // Maxmind
88
+ // since version 2.2.2
89
+ 'ipv4_path' => NULL, // Path to IPv4 DB file
90
+ 'ipv6_path' => NULL, // Path to IPv6 DB file
91
+ // since version 2.2.1
92
+ 'ipv4_last' => 0, // Last-Modified of DB file
93
+ 'ipv6_last' => 0, // Last-Modified of DB file
94
+ ),
95
+ 'IP2Location' => array( // IP2Location
96
+ // since version 2.2.2
97
+ 'ipv4_path' => NULL, // Path to IPv4 DB file
98
+ 'ipv6_path' => NULL, // Path to IPv6 DB file
99
+ // since version 2.2.1
100
+ 'ipv4_last' => 0, // Last-Modified of DB file
101
+ 'ipv6_last' => 0, // Last-Modified of DB file
102
+ ),
103
+ // since version 2.2.3
104
+ 'api_dir' => NULL, // Path to geo-location API
105
+ // since version 2.2.5
106
+ 'exception' => array( // list of exceptional
107
+ 'plugins' => array(), // for pliugins
108
+ 'themes' => array(), // for themes
109
+ // since version 3.0.0
110
+ 'admin' => array(), // for wp-admin
111
+ 'public' => array( // for public facing pages
112
+ 'bbp-new-topic', 'bbp-edit-topic',
113
+ 'bbp-new-reply', 'bbp-edit-reply',
114
+ ),
115
+ 'includes' => array( // for wp-includes/
116
+ 'ms-files.php', 'js/tinymce/wp-tinymce.php'
117
+ ),
118
+ 'uploads' => array(), // for UPLOADS/uploads
119
+ 'languages' => array(), // for wp-content/language
120
+ ),
121
+ // since version 2.2.7
122
+ 'api_key' => array( // API key
123
+ 'GoogleMap' => 'default',
124
+ ),
125
+ // since version 2.2.8
126
+ 'login_action' => array( // Actions for wp-login.php
127
+ 'login' => TRUE,
128
+ 'register' => TRUE,
129
+ 'resetpasss' => TRUE,
130
+ 'lostpassword' => TRUE,
131
+ 'postpass' => TRUE,
132
+ ),
133
+ // since version 3.0.0
134
+ 'response_msg' => 'Sorry, your request cannot be accepted.', // message on blocking
135
+ 'redirect_uri' => 'http://blackhole.webpagetest.org/', // redirection on blocking
136
+ 'network_wide' => FALSE, // settings page on network dashboard
137
+ 'public' => array(
138
+ 'matching_rule' => -1, // -1:follow, 0:white list, 1:black list
139
+ 'white_list' => NULL, // Comma separeted country code
140
+ 'black_list' => 'ZZ', // Comma separeted country code
141
+ 'target_rule' => 0, // 0:all requests, 1:specify the target
142
+ 'target_pages' => array(), // blocking target of pages
143
+ 'target_posts' => array(), // blocking target of post types
144
+ 'target_cates' => array(), // blocking target of categories
145
+ 'target_tags' => array(), // blocking target of tags
146
+ 'ua_list' => "Google:HOST,bot:HOST,slurp:HOST\nspider:HOST,archive:HOST,*:FEED\n*:HOST=embed.ly,Twitterbot:US,Facebot:US",
147
+ 'simulate' => FALSE,// just simulate, never block
148
+ ),
149
+ );
150
+
151
+ /**
152
+ * I/F for option table
153
+ *
154
+ */
155
+ public static function get_default() {
156
+ return self::$option_table;
157
+ }
158
+
159
+ /**
160
+ * Upgrade option table
161
+ *
162
+ */
163
+ public static function upgrade() {
164
+ $default = self::get_default();
165
+
166
+ if ( FALSE === ( $settings = get_option( IP_Geo_Block::OPTION_NAME ) ) ) {
167
+ // save package version number
168
+ $version = $default['version'] = IP_Geo_Block::VERSION;
169
+
170
+ // create new option table
171
+ $settings = $default;
172
+ add_option( IP_Geo_Block::OPTION_NAME, $default );
173
+ }
174
+
175
+ else {
176
+ $version = $settings['version'];
177
+
178
+ // refresh if it's too old
179
+ if ( version_compare( $version, '2.0.0' ) < 0 )
180
+ $settings = $default;
181
+
182
+ if ( version_compare( $version, '2.0.8' ) < 0 )
183
+ $settings['priority'] = $default['priority'];
184
+
185
+ if ( version_compare( $version, '2.1.0' ) < 0 ) {
186
+ foreach ( array( 'plugins', 'themes' ) as $tmp ) {
187
+ $settings['validation'][ $tmp ] = $default['validation'][ $tmp ];
188
+ }
189
+ }
190
+
191
+ if ( version_compare( $version, '2.2.0' ) < 0 ) {
192
+ foreach ( array( 'anonymize', 'signature', 'extra_ips', 'rewrite' ) as $tmp ) {
193
+ $settings[ $tmp ] = $default[ $tmp ];
194
+ }
195
+
196
+ foreach ( array( 'admin', 'ajax' ) as $tmp ) {
197
+ if ( $settings['validation'][ $tmp ] == 2 )
198
+ $settings['validation'][ $tmp ] = 3; // WP-ZEP + Block by country
199
+ }
200
+ }
201
+
202
+ if ( version_compare( $version, '2.2.1' ) < 0 ) {
203
+ foreach ( array( 'Maxmind', 'IP2Location' ) as $tmp ) {
204
+ $settings[ $tmp ] = $default[ $tmp ];
205
+ }
206
+ }
207
+
208
+ if ( version_compare( $version, '2.2.2' ) < 0 ) {
209
+ $tmp = get_option( 'ip_geo_block_statistics' );
210
+ $tmp['daystats'] = array();
211
+ IP_Geo_Block_Logs::record_stat( $tmp );
212
+ delete_option( 'ip_geo_block_statistics' ); // @since 1.2.0
213
+
214
+ foreach ( array( 'maxmind', 'ip2location' ) as $tmp ) {
215
+ unset( $settings[ $tmp ] );
216
+ }
217
+ }
218
+
219
+ if ( version_compare( $version, '2.2.3' ) < 0 )
220
+ $settings['api_dir'] = $default['api_dir'];
221
+
222
+ if ( version_compare( $version, '2.2.5' ) < 0 ) {
223
+ // https://wordpress.org/support/topic/compatibility-with-ag-custom-admin
224
+ $arr = array();
225
+
226
+ foreach ( explode( ',', $settings['signature'] ) as $tmp ) {
227
+ $tmp = trim( $tmp );
228
+ if ( 'wp-config.php' === $tmp || 'passwd' === $tmp )
229
+ $tmp = '/' . $tmp;
230
+ array_push( $arr, $tmp );
231
+ }
232
+
233
+ $settings['signature'] = implode( ',', $arr );
234
+
235
+ foreach ( array( 'plugins', 'themes' ) as $tmp ) {
236
+ $settings['exception'][ $tmp ] = $default['exception'][ $tmp ];
237
+ }
238
+ }
239
+
240
+ if ( version_compare( $version, '2.2.6' ) < 0 ) {
241
+ $settings['signature'] = str_replace( " ", "\n", $settings['signature'] );
242
+ $settings['extra_ips']['white_list'] = str_replace( " ", "\n", $settings['extra_ips']['white_list'] );
243
+ $settings['extra_ips']['black_list'] = str_replace( " ", "\n", $settings['extra_ips']['black_list'] );
244
+
245
+ foreach ( array( 'plugins', 'themes' ) as $tmp ) {
246
+ $arr = array_keys( $settings['exception'][ $tmp ] );
247
+ if ( ! empty( $arr ) && ! is_numeric( $arr[0] ) )
248
+ $settings['exception'][ $tmp ] = $arr;
249
+ }
250
+ }
251
+
252
+ if ( version_compare( $version, '2.2.7' ) < 0 )
253
+ $settings['api_key'] = $default['api_key'];
254
+
255
+ if ( version_compare( $version, '2.2.8' ) < 0 ) {
256
+ $settings['login_action'] = $default['login_action'];
257
+ // Block by country (register, lost password)
258
+ if ( 2 === (int)$settings['validation']['login'] )
259
+ $settings['login_action']['login'] = FALSE;
260
+ }
261
+
262
+ if ( version_compare( $version, '2.2.9' ) < 0 ) {
263
+ $settings['validation']['timing' ] = $default['validation']['timing' ];
264
+ $settings['validation']['recdays'] = $default['validation']['recdays'];
265
+ }
266
+
267
+ if ( version_compare( $version, '3.0.0' ) < 0 ) {
268
+ foreach ( array( 'cache_time_gc', 'response_msg', 'redirect_uri', 'network_wide', 'public' ) as $tmp ) {
269
+ $settings[ $tmp ] = $default[ $tmp ];
270
+ }
271
+
272
+ foreach ( array( 'public', 'includes', 'uploads', 'languages' ) as $tmp ) {
273
+ $settings['validation'][ $tmp ] = $default['validation'][ $tmp ];
274
+ $settings['rewrite' ][ $tmp ] = $default['rewrite' ][ $tmp ];
275
+ $settings['exception' ][ $tmp ] = $default['exception' ][ $tmp ];
276
+ }
277
+
278
+ $settings['exception']['admin'] = $default['exception']['admin'];
279
+ }
280
+
281
+ if ( version_compare( $version, '3.0.1' ) < 0 )
282
+ delete_transient( IP_Geo_Block::CACHE_NAME ); // @since 2.8
283
+
284
+ // save package version number
285
+ $settings['version'] = IP_Geo_Block::VERSION;
286
+ }
287
+
288
+ // install addons for IP Geolocation database API @since 1.1.6
289
+ if ( ! $settings['api_dir'] || version_compare( $version, '3.0.1' ) < 0 )
290
+ $settings['api_dir'] = self::install_api( $settings );
291
+
292
+ // update option table
293
+ update_option( IP_Geo_Block::OPTION_NAME, $settings );
294
+
295
+ // return upgraded settings
296
+ return $settings;
297
+ }
298
+
299
+ /**
300
+ * Install / Uninstall APIs
301
+ *
302
+ */
303
+ public static function install_api( $settings ) {
304
+ $src = IP_GEO_BLOCK_PATH . 'wp-content/' . IP_Geo_Block::GEOAPI_NAME;
305
+ $dst = self::get_api_dir( $settings );
306
+
307
+ try {
308
+ if ( $src !== $dst )
309
+ self::recurse_copy( $src, $dst );
310
+
311
+ } catch ( Exception $e ) {
312
+ if ( class_exists( 'IP_Geo_Block_Admin' ) )
313
+ IP_Geo_Block_Admin::add_admin_notice( 'error', sprintf( __( 'Unable to write %s. Please check the permission.', 'ip-geo-block' ), $dst ) );
314
+
315
+ return NULL;
316
+ }
317
+
318
+ return $dst;
319
+ }
320
+
321
+ public static function delete_api( $settings ) {
322
+ if ( @is_writable( $dir = self::get_api_dir( $settings ) ) )
323
+ self::recurse_rmdir( $dir );
324
+ }
325
+
326
+ private static function get_api_dir( $settings ) {
327
+ // wp-content
328
+ $dir = empty( $settings['api_dir'] ) ? WP_CONTENT_DIR : dirname( $settings['api_dir'] );
329
+
330
+ if ( ! @is_writable( $dir ) ) {
331
+ // wp-content/uploads
332
+ $dir = wp_upload_dir();
333
+ $dir = $dir['basedir'];
334
+
335
+ if ( ! @is_writable( $dir ) ) {
336
+ // wp-content/plugins/ip-geo-block
337
+ if ( ! @is_writable( $dir = IP_GEO_BLOCK_PATH ) )
338
+ $dir = NULL;
339
+ }
340
+ }
341
+
342
+ return IP_Geo_Block_Util::slashit(
343
+ apply_filters( IP_Geo_Block::PLUGIN_NAME . '-api-dir', $dir )
344
+ ) . IP_Geo_Block::GEOAPI_NAME; // must add `ip-geo-api` for basename
345
+ }
346
+
347
+ // http://php.net/manual/function.copy.php#91010
348
+ private static function recurse_copy( $src, $dst ) {
349
+ $src = IP_Geo_Block_Util::slashit( $src );
350
+ $dst = IP_Geo_Block_Util::slashit( $dst );
351
+
352
+ ! @is_dir( $dst ) and wp_mkdir_p( $dst ); // @since 2.0.1 @mkdir( $dst );
353
+
354
+ if ( $dir = @opendir( $src ) ) {
355
+ while( FALSE !== ( $file = readdir( $dir ) ) ) {
356
+ if ( '.' !== $file && '..' !== $file ) {
357
+ if ( @is_dir( $src.$file ) )
358
+ self::recurse_copy( $src.$file, $dst.$file );
359
+ else
360
+ @copy( $src.$file, $dst.$file );
361
+ }
362
+ }
363
+
364
+ closedir( $dir );
365
+ }
366
+ }
367
+
368
+ // http://php.net/manual/function.rmdir.php#110489
369
+ private static function recurse_rmdir( $dir ) {
370
+ $dir = IP_Geo_Block_Util::slashit( $dir );
371
+ $files = array_diff( @scandir( $dir ), array( '.', '..' ) );
372
+
373
+ foreach ( $files as $file ) {
374
+ if ( is_dir( $dir.$file ) )
375
+ self::recurse_rmdir( $dir.$file );
376
+ else
377
+ @unlink( $dir.$file );
378
+ }
379
+
380
+ return @rmdir( $dir );
381
+ }
382
+
383
+ /**
384
+ * Activate / Deactivate Must-use plugin / Advanced cache
385
+ *
386
+ */
387
+ private static function remove_mu_plugin() {
388
+ if ( file_exists( $src = WPMU_PLUGIN_DIR . '/ip-geo-block-mu.php' ) )
389
+ return @unlink( $src ) ? TRUE : $src;
390
+ else
391
+ return TRUE;
392
+ }
393
+
394
+ public static function get_validation_timing() {
395
+ if ( file_exists( WPMU_PLUGIN_DIR . '/ip-geo-block-mu.php' ) )
396
+ return 1; // mu-plugins
397
+
398
+ return 0;
399
+ }
400
+
401
+ public static function setup_validation_timing( $settings = NULL ) {
402
+ switch ( $settings ? (int)$settings['validation']['timing'] : 0 ) {
403
+ case 0: // init
404
+ if ( TRUE !== ( $src = self::remove_mu_plugin() ) )
405
+ return $src;
406
+ break;
407
+
408
+ case 1: // mu-plugins
409
+ $src = IP_GEO_BLOCK_PATH . 'wp-content/mu-plugins/ip-geo-block-mu.php';
410
+ $dst = WPMU_PLUGIN_DIR . '/ip-geo-block-mu.php';
411
+
412
+ if ( ! file_exists( $dst ) ) {
413
+ if ( ! file_exists( WPMU_PLUGIN_DIR ) )
414
+ wp_mkdir_p( WPMU_PLUGIN_DIR ); // @since 2.0.1 @mkdir( $path );
415
+
416
+ if ( ! @copy( $src, $dst ) )
417
+ return $dst;
418
+ }
419
+ break;
420
+ }
421
+
422
+ return TRUE;
423
+ }
424
+
425
+ }
classes/class-ip-geo-block-util.php ADDED
@@ -0,0 +1,515 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IP Geo Block - Utilities
4
+ *
5
+ * @package IP_Geo_Block
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2016 tokkonopapa
10
+ */
11
+
12
+ class IP_Geo_Block_Util {
13
+
14
+ /**
15
+ * Return local time of day.
16
+ *
17
+ */
18
+ public static function localdate( $timestamp = FALSE, $fmt = NULL ) {
19
+ static $offset = NULL;
20
+ static $format = NULL;
21
+
22
+ if ( NULL === $offset )
23
+ $offset = wp_timezone_override_offset() * HOUR_IN_SECONDS;
24
+
25
+ if ( NULL === $format )
26
+ $format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' );
27
+
28
+ return date_i18n( $fmt ? $fmt : $format, $timestamp ? (int)$timestamp + $offset : FALSE );
29
+ }
30
+
31
+ /**
32
+ * Download zip/gz file, uncompress and save it to specified file
33
+ *
34
+ */
35
+ public static function download_zip( $url, $args, $filename, $modified ) {
36
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-cron.php';
37
+ return IP_Geo_Block_Cron::download_zip( $url, $args, $filename, $modified );
38
+ }
39
+
40
+ /**
41
+ * Simple comparison of urls
42
+ *
43
+ */
44
+ public static function compare_url( $a, $b ) {
45
+ if ( ! ( $a = @parse_url( $a ) ) ) return FALSE;
46
+ if ( ! ( $b = @parse_url( $b ) ) ) return FALSE;
47
+
48
+ // leave scheme to site configuration because is_ssl() doesn’t work behind some load balancers.
49
+ unset( $a['scheme'] );
50
+ unset( $b['scheme'] );
51
+
52
+ // $_SERVER['HTTP_HOST'] can't be available in case of malicious url.
53
+ $key = isset( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : '';
54
+ if ( empty( $a['host'] ) ) $a['host'] = $key;
55
+ if ( empty( $b['host'] ) ) $b['host'] = $key;
56
+
57
+ $key = array_diff( $a, $b );
58
+ return empty( $key ) ? TRUE : FALSE;
59
+ }
60
+
61
+ /**
62
+ * Explod with multiple delimiter.
63
+ *
64
+ */
65
+ public static function multiexplode ( $delimiters, $string ) {
66
+ return array_filter( explode( $delimiters[0], str_replace( $delimiters, $delimiters[0], $string ) ) );
67
+ }
68
+
69
+ /**
70
+ * HTML/XHTML filter that only allows some elements and attributes
71
+ *
72
+ * @see wp-includes/kses.php
73
+ */
74
+ public static function kses( $str, $allow_tags = TRUE ) {
75
+ // wp_kses() is unavailable on advanced-cache.php
76
+ return wp_kses( $str, $allow_tags ? $GLOBALS['allowedtags'] : array() );
77
+ }
78
+
79
+ /**
80
+ * Retrieve nonce from queries or referrer
81
+ *
82
+ */
83
+ public static function retrieve_nonce( $key ) {
84
+ if ( isset( $_REQUEST[ $key ] ) )
85
+ return preg_replace( '/[^\w]/', '', $_REQUEST[ $key ] );
86
+
87
+ if ( preg_match( "/$key(?:=|%3D)([\w]+)/", self::get_referer(), $matches ) )
88
+ return preg_replace( '/[^\w]/', '', $matches[1] );
89
+
90
+ return NULL;
91
+ }
92
+
93
+ public static function trace_nonce( $nonce ) {
94
+ if ( self::may_be_logged_in() && empty( $_REQUEST[ $nonce ] ) &&
95
+ self::retrieve_nonce( $nonce ) && 'GET' === $_SERVER['REQUEST_METHOD'] ) {
96
+ // add nonce at add_admin_nonce() to handle the client side redirection.
97
+ self::redirect( esc_url_raw( $_SERVER['REQUEST_URI'] ), 302 );
98
+ exit;
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Retrieve nonce and rebuild query strings.
104
+ *
105
+ */
106
+ public static function rebuild_nonce( $location, $status = 302 ) {
107
+ // check if the location is internal
108
+ $host = parse_url( $location, PHP_URL_HOST );
109
+ if ( ! $host || $host === parse_url( home_url(), PHP_URL_HOST ) ) {
110
+ // it doesn't care about valid nonce or invalid nonce (must be sanitized)
111
+ if ( $nonce = self::retrieve_nonce( $key = IP_Geo_Block::PLUGIN_NAME . '-auth-nonce' ) ) {
112
+ $location = esc_url_raw( add_query_arg(
113
+ array(
114
+ $key => false, // delete onece
115
+ $key => $nonce // add again
116
+ ),
117
+ $location
118
+ ) );
119
+ }
120
+ }
121
+
122
+ return $location;
123
+ }
124
+
125
+ /**
126
+ * WP alternative function of wp_create_nonce() for mu-plugins
127
+ *
128
+ * Creates a cryptographic tied to the action, user, session, and time.
129
+ * @source wp-includes/pluggable.php
130
+ */
131
+ public static function create_nonce( $action = -1 ) {
132
+ $uid = self::get_current_user_id();
133
+ $tok = self::get_session_token();
134
+ $exp = self::nonce_tick();
135
+
136
+ return substr( self::hash_nonce( $exp . '|' . $action . '|' . $uid . '|' . $tok ), -12, 10 );
137
+ }
138
+
139
+ /**
140
+ * WP alternative function of wp_verify_nonce() for mu-plugins
141
+ *
142
+ * Verify that correct nonce was used with time limit.
143
+ * @source wp-includes/pluggable.php
144
+ */
145
+ public static function verify_nonce( $nonce, $action = -1 ) {
146
+ $uid = self::get_current_user_id();
147
+ $tok = self::get_session_token();
148
+ $exp = self::nonce_tick();
149
+
150
+ // Nonce generated 0-12 hours ago
151
+ $expected = substr( self::hash_nonce( $exp . '|' . $action . '|' . $uid . '|' . $tok ), -12, 10 );
152
+ if ( self::hash_equals( $expected, (string)$nonce ) ) {
153
+ return 1;
154
+ }
155
+
156
+ // Nonce generated 12-24 hours ago
157
+ $expected = substr( self::hash_nonce( ( $exp - 1 ) . '|' . $action . '|' . $uid . '|' . $tok ), -12, 10 );
158
+ if ( self::hash_equals( $expected, (string)$nonce ) ) {
159
+ return 2;
160
+ }
161
+
162
+ // Invalid nonce
163
+ return FALSE;
164
+ }
165
+
166
+ /**
167
+ * WP alternative function of wp_hash() for mu-plugins
168
+ *
169
+ * Get hash of given string for nonce.
170
+ * @source wp-includes/pluggable.php
171
+ */
172
+ private static function hash_nonce( $data ) {
173
+ return self::hash_hmac( 'md5', $data, NONCE_KEY . NONCE_SALT );
174
+ }
175
+
176
+ /**
177
+ * WP alternative function for mu-plugins
178
+ *
179
+ * Retrieve the current session token from the logged_in cookie.
180
+ * @source wp-includes/user.php
181
+ */
182
+ private static function get_session_token() {
183
+ // Arrogating logged_in cookie never cause the privilege escalation.
184
+ $cookie = self::parse_auth_cookie( 'logged_in' );
185
+ return ! empty( $cookie['token'] ) ? $cookie['token'] : AUTH_KEY . AUTH_SALT;
186
+ }
187
+
188
+ /**
189
+ * WP alternative function for mu-plugins
190
+ *
191
+ * Parse a cookie into its components. It assumes the key including $scheme.
192
+ * @source wp-includes/pluggable.php (after muplugins_loaded, it would be initialized)
193
+ */
194
+ private static function parse_auth_cookie( $scheme ) {
195
+ static $cookie = FALSE;
196
+
197
+ if ( FALSE === $cookie ) {
198
+ foreach ( array_keys( $_COOKIE ) as $key ) {
199
+ if ( FALSE !== strpos( $key, $scheme ) ) {
200
+ if ( count( $elements = explode( '|', $_COOKIE[ $key ] ) ) === 4 ) {
201
+ @list( $username, $expiration, $token, $hmac ) = $elements;
202
+ return $cookie = compact( 'username', 'expiration', 'token', 'hmac' );
203
+ }
204
+ }
205
+ }
206
+ }
207
+
208
+ return $cookie;
209
+ }
210
+
211
+ /**
212
+ * WP alternative function for mu-plugins
213
+ *
214
+ * Get the time-dependent variable for nonce creation.
215
+ * @source wp-includes/pluggable.php
216
+ */
217
+ private static function nonce_tick() {
218
+ return ceil( time() / ( DAY_IN_SECONDS / 2 ) );
219
+ }
220
+
221
+ /**
222
+ * WP alternative function of hash_equals() for mu-plugins
223
+ *
224
+ * Timing attack safe string comparison.
225
+ * @source http://php.net/manual/en/function.hash-equals.php#115635
226
+ * @see http://php.net/manual/en/language.operators.increment.php
227
+ * @see wp-includes/compat.php
228
+ */
229
+ private static function hash_equals( $a, $b ) {
230
+ // PHP 5 >= 5.6.0 or wp-includes/compat.php
231
+ if ( function_exists( 'hash_equals' ) )
232
+ return hash_equals( $a, $b );
233
+
234
+ if( ( $i = strlen( $a ) ) !== strlen( $b ) )
235
+ return FALSE;
236
+
237
+ $exp = $a ^ $b; // length of both $a and $b are same
238
+ $ret = 0;
239
+
240
+ while ( --$i >= 0 ) {
241
+ $ret |= ord( $exp[ $i ] );
242
+ }
243
+
244
+ return ! $ret;
245
+ }
246
+
247
+ /**
248
+ * WP alternative function of hash_hmac() for mu-plugins
249
+ *
250
+ * Generate a keyed hash value using the HMAC method.
251
+ * @source http://php.net/manual/en/function.hash-hmac.php#93440
252
+ */
253
+ private static function hash_hmac( $algo, $data, $key, $raw_output = FALSE ) {
254
+ // PHP 5 >= 5.1.2, PECL hash >= 1.1 or wp-includes/compat.php
255
+ if ( function_exists( 'hash_hmac' ) )
256
+ return hash_hmac( $algo, $data, $key, $raw_output );
257
+
258
+ $packs = array( 'md5' => 'H32', 'sha1' => 'H40' );
259
+
260
+ if ( ! isset( $packs[ $algo ] ) )
261
+ return FALSE;
262
+
263
+ $pack = $packs[ $algo ];
264
+
265
+ if ( strlen( $key ) > 64 )
266
+ $key = pack( $pack, $algo( $key ) );
267
+
268
+ $key = str_pad( $key, 64, chr(0) );
269
+
270
+ $ipad = ( substr( $key, 0, 64 ) ^ str_repeat( chr(0x36), 64 ) );
271
+ $opad = ( substr( $key, 0, 64 ) ^ str_repeat( chr(0x5C), 64 ) );
272
+
273
+ $hmac = $algo( $opad . pack( $pack, $algo( $ipad . $data ) ) );
274
+
275
+ return $raw_output ? pack( $pack, $hmac ) : $hmac;
276
+ }
277
+
278
+ /**
279
+ * WP alternative function of wp_sanitize_redirect() for mu-plugins
280
+ *
281
+ * Sanitizes a URL for use in a redirect.
282
+ * @source wp-includes/pluggable.php
283
+ */
284
+ private static function sanitize_utf8_in_redirect( $matches ) {
285
+ return urlencode( $matches[0] );
286
+ }
287
+
288
+ private static function sanitize_redirect( $location ) {
289
+ $regex = '/
290
+ (
291
+ (?: [\xC2-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
292
+ | \xE0[\xA0-\xBF][\x80-\xBF] # triple-byte sequences 1110xxxx 10xxxxxx * 2
293
+ | [\xE1-\xEC][\x80-\xBF]{2}
294
+ | \xED[\x80-\x9F][\x80-\xBF]
295
+ | [\xEE-\xEF][\x80-\xBF]{2}
296
+ | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3
297
+ | [\xF1-\xF3][\x80-\xBF]{3}
298
+ | \xF4[\x80-\x8F][\x80-\xBF]{2}
299
+ ){1,40} # ...one or more times
300
+ )/x';
301
+ $location = preg_replace_callback( $regex, array( __CLASS__, 'sanitize_utf8_in_redirect' ), $location );
302
+ $location = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:%!*\[\]()@]|i', '', $location );
303
+ $location = self::kses_no_null( $location ); // wp-includes/kses.php
304
+
305
+ // remove %0d and %0a from location
306
+ $strip = array( '%0d', '%0a', '%0D', '%0A' );
307
+ return self::deep_replace( $strip, $location ); // wp-includes/formatting.php
308
+ }
309
+
310
+ /**
311
+ * WP alternative function of wp_redirect() for mu-plugins
312
+ *
313
+ * Redirects to another page.
314
+ * @source wp-includes/pluggable.php
315
+ */
316
+ public static function redirect( $location, $status = 302 ) {
317
+ $_is_apache = ( strpos( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) !== FALSE || strpos( $_SERVER['SERVER_SOFTWARE'], 'LiteSpeed' ) !== FALSE );
318
+ $_is_IIS = ! $_is_apache && ( strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) !== FALSE || strpos( $_SERVER['SERVER_SOFTWARE'], 'ExpressionDevServer' ) !== FALSE );
319
+
320
+ // retrieve nonce from referer and add it to the location
321
+ $location = self::rebuild_nonce( $location, $status );
322
+ $location = self::sanitize_redirect( $location );
323
+
324
+ if ( $location ) {
325
+ if ( ! $_is_IIS && PHP_SAPI != 'cgi-fcgi' )
326
+ status_header( $status ); // This causes problems on IIS and some FastCGI setups
327
+
328
+ header( "Location: $location", true, $status );
329
+
330
+ return TRUE;
331
+ }
332
+
333
+ else {
334
+ return FALSE;
335
+ }
336
+ }
337
+
338
+ /**
339
+ * WP alternative function of wp_redirect() for mu-plugins
340
+ *
341
+ * Performs a safe (local) redirect, using redirect().
342
+ * @source wp-includes/pluggable.php
343
+ */
344
+ public static function safe_redirect( $location, $status = 302 ) {
345
+ // Need to look at the URL the way it will end up in wp_redirect()
346
+ $location = self::sanitize_redirect( $location );
347
+
348
+ // Filters the redirect fallback URL for when the provided redirect is not safe (local).
349
+ $location = self::validate_redirect( $location, apply_filters( 'wp_safe_redirect_fallback', admin_url(), $status ) );
350
+
351
+ self::redirect( $location, $status );
352
+ }
353
+
354
+ /**
355
+ * WP alternative function of wp_validate_redirect() for mu-plugins
356
+ *
357
+ * Validates a URL for use in a redirect.
358
+ * @source wp-includes/pluggable.php
359
+ */
360
+ private static function validate_redirect( $location, $default = '' ) {
361
+ // browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//'
362
+ if ( substr( $location = trim( $location ), 0, 2 ) == '//' )
363
+ $location = 'http:' . $location;
364
+
365
+ // In php 5 parse_url may fail if the URL query part contains http://, bug #38143
366
+ $test = ( $cut = strpos( $location, '?' ) ) ? substr( $location, 0, $cut ) : $location;
367
+
368
+ // @-operator is used to prevent possible warnings in PHP < 5.3.3.
369
+ $lp = @parse_url( $test );
370
+
371
+ // Give up if malformed URL
372
+ if ( FALSE === $lp )
373
+ return $default;
374
+
375
+ // Allow only http and https schemes. No data:, etc.
376
+ if ( isset( $lp['scheme'] ) && ! ( 'http' == $lp['scheme'] || 'https' == $lp['scheme'] ) )
377
+ return $default;
378
+
379
+ // Reject if certain components are set but host is not. This catches urls like https:host.com for which parse_url does not set the host field.
380
+ if ( ! isset( $lp['host'] ) && ( isset( $lp['scheme'] ) || isset( $lp['user'] ) || isset( $lp['pass'] ) || isset( $lp['port'] ) ) )
381
+ return $default;
382
+
383
+ // Reject malformed components parse_url() can return on odd inputs.
384
+ foreach ( array( 'user', 'pass', 'host' ) as $component ) {
385
+ if ( isset( $lp[ $component ] ) && strpbrk( $lp[ $component ], ':/?#@' ) )
386
+ return $default;
387
+ }
388
+
389
+ $wpp = parse_url( home_url() );
390
+
391
+ // Filters the whitelist of hosts to redirect to.
392
+ $allowed_hosts = (array) apply_filters( 'allowed_redirect_hosts', array( $wpp['host'] ), isset( $lp['host'] ) ? $lp['host'] : '' );
393
+ $allowed_hosts[] = 'blackhole.webpagetest.org';
394
+
395
+ if ( isset( $lp['host'] ) && ( ! in_array( $lp['host'], $allowed_hosts ) && $lp['host'] != strtolower( $wpp['host'] ) ) )
396
+ $location = $default;
397
+
398
+ return $location;
399
+ }
400
+
401
+ /**
402
+ * WP alternative function of wp_get_raw_referer() for mu-plugins
403
+ *
404
+ * Retrieves unvalidated referer from '_wp_http_referer' or HTTP referer.
405
+ * @source wp-includes/functions.php
406
+ * @uses wp_unslash() can be replaced with stripslashes() in this context because the target value is 'string'.
407
+ */
408
+ private static function get_raw_referer() {
409
+ if ( ! empty( $_REQUEST['_wp_http_referer'] ) )
410
+ return /*wp_unslash*/ stripslashes( $_REQUEST['_wp_http_referer'] ); // wp-includes/formatting.php
411
+
412
+ elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) )
413
+ return /*wp_unslash*/ stripslashes( $_SERVER['HTTP_REFERER'] ); // wp-includes/formatting.php
414
+
415
+ return FALSE;
416
+ }
417
+
418
+ /**
419
+ * WP alternative function of wp_get_referer() for mu-plugins
420
+ *
421
+ * Retrieve referer from '_wp_http_referer' or HTTP referer.
422
+ * @source wp-includes/functions.php
423
+ */
424
+ public static function get_referer() {
425
+ $ref = self::get_raw_referer(); // wp-includes/functions.php
426
+ $req = /*wp_unslash*/ stripslashes( $_SERVER['REQUEST_URI'] );
427
+
428
+ if ( $ref && $ref !== $req && $ref !== home_url() . $req )
429
+ return self::validate_redirect( $ref, FALSE );
430
+
431
+ return FALSE;
432
+ }
433
+
434
+ /**
435
+ * WP alternative function of is_user_logged_in() for mu-plugins
436
+ *
437
+ * Checks if the current visitor is a logged in user.
438
+ * @source wp-includes/pluggable.php
439
+ */
440
+ public static function may_be_logged_in() {
441
+ // possibly logged in but should be verified after 'init' hook is fired.
442
+ return did_action( 'init' ) ? is_user_logged_in() : ( self::parse_auth_cookie( 'logged_in' ) ? TRUE : FALSE );
443
+ }
444
+
445
+ /**
446
+ * WP alternative function of get_current_user_id() for mu-plugins
447
+ *
448
+ * Get the current user's ID.
449
+ * @source wp-includes/user.php
450
+ */
451
+ public static function get_current_user_id() {
452
+ static $uid = 0;
453
+
454
+ if ( ! $uid ) {
455
+ $uid = did_action( 'init' ) ? get_current_user_id() : 0;
456
+
457
+ if ( ! $uid && isset( $_COOKIE ) ) {
458
+ foreach ( array_keys( $_COOKIE ) as $key ) {
459
+ if ( 0 === strpos( $key, 'wp-settings-' ) ) {
460
+ $uid = substr( $key, strrpos( $key, '-' ) + 1 ); // get numerical characters
461
+ break;
462
+ }
463
+ }
464
+ }
465
+ }
466
+
467
+ return $uid;
468
+ }
469
+
470
+ /**
471
+ * WP alternative function for advanced-cache.php
472
+ *
473
+ * Add / Remove slash at the end of string.
474
+ * @source wp-includes/formatting.php
475
+ */
476
+ public static function unslashit( $string ) {
477
+ return rtrim( $string, '/\\' );
478
+ }
479
+
480
+ public static function slashit( $string ) {
481
+ return rtrim( $string, '/\\' ) . '/';
482
+ }
483
+
484
+ /**
485
+ * WP alternative function of wp_kses_no_null() for advanced-cache.php
486
+ *
487
+ * Removes any NULL characters in $string.
488
+ * @source wp-includes/kses.php
489
+ */
490
+ private static function kses_no_null( $string ) {
491
+ $string = preg_replace( '/[\x00-\x08\x0B\x0C\x0E-\x1F]/', '', $string );
492
+ $string = preg_replace( '/\\\\+0+/', '', $string );
493
+
494
+ return $string;
495
+ }
496
+
497
+ /**
498
+ * WP alternative function of _deep_replace() for advanced-cache.php
499
+ *
500
+ * Perform a deep string replace operation to ensure the values in $search are no longer present.
501
+ * e.g. $subject = '%0%0%0DDD', $search ='%0D', $result ='' rather than the '%0%0DD' that str_replace would return
502
+ * @source wp-includes/formatting.php
503
+ */
504
+ private static function deep_replace( $search, $subject ) {
505
+ $subject = (string) $subject;
506
+
507
+ $count = 1;
508
+ while ( $count ) {
509
+ $subject = str_replace( $search, '', $subject, $count );
510
+ }
511
+
512
+ return $subject;
513
+ }
514
+
515
+ }
classes/class-ip-geo-block.php ADDED
@@ -0,0 +1,880 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IP Geo Block
4
+ *
5
+ * @package IP_Geo_Block
6
+ * @author tokkonopapa <tokkonopapa@yahoo.com>
7
+ * @license GPL-2.0+
8
+ * @link http://www.ipgeoblock.com/
9
+ * @copyright 2013-2016 tokkonopapa
10
+ */
11
+
12
+ class IP_Geo_Block {
13
+
14
+ /**
15
+ * Unique identifier for this plugin.
16
+ *
17
+ */
18
+ const VERSION = '3.0.1.2';
19
+ const GEOAPI_NAME = 'ip-geo-api';
20
+ const PLUGIN_NAME = 'ip-geo-block';
21
+ const OPTION_NAME = 'ip_geo_block_settings';
22
+ const CACHE_NAME = 'ip_geo_block_cache';
23
+ const CRON_NAME = 'ip_geo_block_cron';
24
+
25
+ /**
26
+ * Instance of this class.
27
+ *
28
+ */
29
+ protected static $instance = NULL;
30
+
31
+ // Globals in this class
32
+ public static $wp_path;
33
+ private $pagenow = NULL;
34
+ private $request_uri = NULL;
35
+ private $target_type = NULL;
36
+ private $remote_addr = NULL;
37
+
38
+ /**
39
+ * Initialize the plugin
40
+ *
41
+ */
42
+ private function __construct() {
43
+ $settings = self::get_option();
44
+ $priority = &$settings['priority'];
45
+ $validate = &$settings['validation'];
46
+ $loader = new IP_Geo_Block_Loader();
47
+
48
+ // include drop in if it exists
49
+ $key = IP_Geo_Block_Util::unslashit( $settings['api_dir'] ) . '/drop-in.php';
50
+ file_exists( $key ) and include( $key );
51
+
52
+ // Garbage collection for IP address cache
53
+ add_action( self::CACHE_NAME, array( $this, 'exec_cache_gc' ) );
54
+
55
+ // the action hook which will be fired by cron job
56
+ if ( $settings['update']['auto'] )
57
+ add_action( self::CRON_NAME, array( $this, 'update_database' ) );
58
+
59
+ // check the package version and upgrade if needed (activation hook never fire on upgrade)
60
+ if ( version_compare( $settings['version'], self::VERSION ) < 0 || $settings['matching_rule'] < 0 )
61
+ $loader->add_action( 'init', 'ip_geo_block_activate', $priority );
62
+
63
+ // normalize requested uri and page
64
+ $key = preg_replace( array( '!\.+/!', '!//+!' ), '/', $_SERVER['REQUEST_URI'] );
65
+ $this->request_uri = @parse_url( $key, PHP_URL_PATH ) or $this->request_uri = $key;
66
+ $this->pagenow = ! empty( $GLOBALS['pagenow'] ) ? $GLOBALS['pagenow'] : basename( $_SERVER['SCRIPT_NAME'] );
67
+
68
+ // setup the content folders
69
+ self::$wp_path = array( 'home' => IP_Geo_Block_Util::unslashit( parse_url( site_url(), PHP_URL_PATH ) ) ); // @since 2.6.0
70
+ $len = strlen( self::$wp_path['home'] );
71
+ $list = array(
72
+ 'admin' => 'admin_url', // @since 2.6.0
73
+ 'plugins' => 'plugins_url', // @since 2.6.0
74
+ 'themes' => 'get_theme_root_uri', // @since 1.5.0
75
+ );
76
+
77
+ // analize the validation target (admin|plugins|themes|includes)
78
+ foreach ( $list as $key => $val ) {
79
+ self::$wp_path[ $key ] = IP_Geo_Block_Util::slashit( substr( parse_url( call_user_func( $val ), PHP_URL_PATH ), $len ) );
80
+ if ( ! $this->target_type && FALSE !== strpos( $this->request_uri, self::$wp_path[ $key ] ) )
81
+ $this->target_type = $key;
82
+ }
83
+
84
+ // validate request to WordPress core files
85
+ $list = array(
86
+ 'wp-comments-post.php' => 'comment',
87
+ 'wp-trackback.php' => 'comment',
88
+ 'xmlrpc.php' => 'xmlrpc',
89
+ 'wp-login.php' => 'login',
90
+ 'wp-signup.php' => 'login',
91
+ );
92
+
93
+ // wp-admin, wp-includes, wp-content/(plugins|themes|language|uploads)
94
+ if ( $this->target_type ) {
95
+ if ( 'admin' !== $this->target_type )
96
+ $loader->add_action( 'init', array( $this, 'validate_direct' ), $priority );
97
+ else // 'widget_init' for admin dashboard
98
+ $loader->add_action( 'wp_loaded', array( $this, 'validate_admin' ), $priority );
99
+ }
100
+
101
+ // analize core validation target (comment|xmlrpc|login|public)
102
+ elseif ( isset( $list[ $this->pagenow ] ) ) {
103
+ if ( $validate[ $list[ $this->pagenow ] ] )
104
+ $loader->add_action( 'init', array( $this, 'validate_' . $list[ $this->pagenow ] ), $priority );
105
+ }
106
+
107
+ // alternative of trackback
108
+ elseif ( 'POST' === $_SERVER['REQUEST_METHOD'] && 'trackback' === basename( $this->request_uri ) ) {
109
+ if ( $validate['comment'] )
110
+ $loader->add_action( 'init', array( $this, 'validate_comment' ), $priority );
111
+ }
112
+
113
+ else {
114
+ // public facing pages
115
+ if ( $validate['public'] /* && 'index.php' === $this->pagenow */ )
116
+ $loader->add_action( 'init', array( $this, 'validate_public' ), $priority );
117
+
118
+ // message text on comment form
119
+ if ( $settings['comment']['pos'] ) {
120
+ $key = ( 1 === (int)$settings['comment']['pos'] ? '_top' : '' );
121
+ add_action( 'comment_form' . $key, array( $this, 'comment_form_message' ) );
122
+ }
123
+
124
+ if ( $validate['comment'] ) {
125
+ add_action( 'pre_comment_on_post', array( $this, 'validate_comment' ), $priority ); // wp-comments-post.php @since 2.8.0
126
+ add_action( 'pre_trackback_post', array( $this, 'validate_comment' ), $priority ); // wp-trackback.php @since 4.7.0
127
+ add_filter( 'preprocess_comment', array( $this, 'validate_comment' ), $priority ); // wp-includes/comment.php @since 1.5.0
128
+
129
+ // bbPress: prevent creating topic/relpy and rendering form
130
+ add_action( 'bbp_post_request_bbp-new-topic', array( $this, 'validate_comment' ), $priority );
131
+ add_action( 'bbp_post_request_bbp-new-reply', array( $this, 'validate_comment' ), $priority );
132
+ add_filter( 'bbp_current_user_can_access_create_topic_form', array( $this, 'validate_front' ), $priority );
133
+ add_filter( 'bbp_current_user_can_access_create_reply_form', array( $this, 'validate_front' ), $priority );
134
+ }
135
+
136
+ if ( $validate['login'] ) {
137
+ // for hide/rename wp-login.php, BuddyPress: prevent registration and rendering form
138
+ add_action( 'login_init', array( $this, 'validate_login' ), $priority );
139
+
140
+ // only when block on front-end is disabled
141
+ if ( ! $validate['public'] ) {
142
+ add_action( 'bp_core_screen_signup', array( $this, 'validate_login' ), $priority );
143
+ add_action( 'bp_signup_pre_validate', array( $this, 'validate_login' ), $priority );
144
+ }
145
+ }
146
+ }
147
+
148
+ // force to change the redirect URL on logout to remove nonce, embed a nonce into pages
149
+ add_filter( 'wp_redirect', array( $this, 'logout_redirect' ), 20, 2 ); // logout_redirect @4.2
150
+ add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_nonce' ), $priority );
151
+
152
+ // Run the loader to execute all of the hooks with WordPress.
153
+ $loader->run( $this );
154
+ unset( $loader );
155
+ }
156
+
157
+ /**
158
+ * I/F for registering custom fileter
159
+ *
160
+ */
161
+ public static function add_filter( $tag, $function, $priority = 10, $args = 1 ) {
162
+ add_filter( $tag, $function, $priority, $args );
163
+ }
164
+
165
+ /**
166
+ * Return an instance of this class.
167
+ *
168
+ */
169
+ public static function get_instance() {
170
+ return self::$instance ? self::$instance : ( self::$instance = new self );
171
+ }
172
+
173
+ /**
174
+ * Optional values handlings.
175
+ *
176
+ */
177
+ public static function get_default() {
178
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php';
179
+ return IP_Geo_Block_Opts::get_default();
180
+ }
181
+
182
+ // get optional values from wp options
183
+ public static function get_option() {
184
+ return FALSE !== ( $option = get_option( self::OPTION_NAME ) ) ? $option : self::get_default();
185
+ }
186
+
187
+ /**
188
+ * Register and enqueue a nonce with a specific JavaScript.
189
+ *
190
+ */
191
+ public static function enqueue_nonce() {
192
+ if ( is_user_logged_in() ) {
193
+ $handle = self::PLUGIN_NAME . '-auth-nonce';
194
+ $script = plugins_url(
195
+ ! defined( 'IP_GEO_BLOCK_DEBUG' ) || ! IP_GEO_BLOCK_DEBUG ?
196
+ 'admin/js/authenticate.min.js' : 'admin/js/authenticate.js', IP_GEO_BLOCK_BASE
197
+ );
198
+ $nonce = array( 'nonce' => IP_Geo_Block_Util::create_nonce( $handle ) ) + self::$wp_path;
199
+ wp_enqueue_script( $handle, $script, array( 'jquery' ), self::VERSION );
200
+ wp_localize_script( $handle, 'IP_GEO_BLOCK_AUTH', $nonce );
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Remove the redirecting URL on logout not to be blocked by WP-ZEP.
206
+ *
207
+ */
208
+ public function logout_redirect( $uri ) {
209
+ if ( isset( $_REQUEST['action'] ) && 'logout' === $_REQUEST['action'] && FALSE !== stripos( $uri, self::$wp_path['admin'] ) )
210
+ return esc_url_raw( add_query_arg( array( 'loggedout' => 'true' ), wp_login_url() ) );
211
+ else
212
+ return $uri;
213
+ }
214
+
215
+ /**
216
+ * Setup the http header.
217
+ *
218
+ * @see http://codex.wordpress.org/Function_Reference/wp_remote_get
219
+ */
220
+ public static function get_request_headers( $settings ) {
221
+ return apply_filters( self::PLUGIN_NAME . '-headers', array(
222
+ 'timeout' => (int)$settings['timeout'],
223
+ 'user-agent' => ! empty( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : 'WordPress/' . $GLOBALS['wp_version'] . ', ' . self::PLUGIN_NAME . ' ' . self::VERSION,
224
+ ) );
225
+ }
226
+
227
+ /**
228
+ * Get current IP address
229
+ *
230
+ */
231
+ public static function get_ip_address() {
232
+ return apply_filters( self::PLUGIN_NAME . '-ip-addr', $_SERVER['REMOTE_ADDR'] );
233
+ }
234
+
235
+ /**
236
+ * Render a text message on the comment form.
237
+ *
238
+ */
239
+ public function comment_form_message() {
240
+ $settings = self::get_option();
241
+ echo '<p id="', self::PLUGIN_NAME, '-msg">', IP_Geo_Block_Util::kses( $settings['comment']['msg'] ), '</p>', "\n";
242
+ }
243
+
244
+ /**
245
+ * Build a validation result for the current user.
246
+ *
247
+ */
248
+ private static function make_validation( $ip, $result ) {
249
+ return array_merge( array(
250
+ 'ip' => $ip,
251
+ 'auth' => IP_Geo_Block_Util::get_current_user_id(),
252
+ 'code' => 'ZZ', // may be overwritten with $result
253
+ ), $result );
254
+ }
255
+
256
+ /**
257
+ * Get geolocation and country code from an ip address.
258
+ *
259
+ * @param string $ip IP address / default: $_SERVER['REMOTE_ADDR']
260
+ * @param array $providers list of providers / ex: array( 'ipinfo.io' )
261
+ * @param string $callback geolocation function / ex: 'get_location'
262
+ * @return array $result country code and so on
263
+ */
264
+ public static function get_geolocation( $ip = NULL, $providers = array(), $callback = 'get_country' ) {
265
+ $settings = self::get_option();
266
+
267
+ if ( empty( $providers ) ) // make valid providers list
268
+ $providers = IP_Geo_Block_Provider::get_valid_providers( $settings['providers'] );
269
+
270
+ $result = self::_get_geolocation( $ip ? $ip : self::get_ip_address(), $settings, $providers, $callback );
271
+
272
+ if ( ! empty( $result['countryCode'] ) )
273
+ $result['code'] = $result['countryCode'];
274
+
275
+ return $result;
276
+ }
277
+
278
+ /**
279
+ * API for internal.
280
+ *
281
+ */
282
+ private static function _get_geolocation( $ip, $settings, $providers, $callback = 'get_country' ) {
283
+ // set arguments for wp_remote_get()
284
+ $args = self::get_request_headers( $settings );
285
+
286
+ foreach ( $providers as $provider ) {
287
+ $time = microtime( TRUE );
288
+ if ( ( $geo = IP_Geo_Block_API::get_instance( $provider, $settings ) ) &&
289
+ ( $code = $geo->$callback( $ip, $args ) ) ) {
290
+ return self::make_validation( $ip, array(
291
+ 'time' => microtime( TRUE ) - $time,
292
+ 'provider' => $provider,
293
+ ) + ( is_array( $code ) ? $code : array( 'code' => $code ) ) );
294
+ }
295
+ }
296
+
297
+ return self::make_validation( $ip, array( 'errorMessage' => 'unknown' ) );
298
+ }
299
+
300
+ /**
301
+ * Validate geolocation by country code.
302
+ *
303
+ */
304
+ public static function validate_country( $hook, $validate, $settings, $block = TRUE ) {
305
+ if ( $block && 0 === (int)$settings['matching_rule'] ) {
306
+ // 'ZZ' will be blocked if it's not in the $list.
307
+ if ( ( $list = $settings['white_list'] ) && FALSE === strpos( $list, $validate['code'] ) )
308
+ return $validate + array( 'result' => 'blocked' ); // can't overwrite existing result
309
+ }
310
+
311
+ elseif( $block && 1 === (int)$settings['matching_rule'] ) {
312
+ // 'ZZ' will NOT be blocked if it's not in the $list.
313
+ if ( ( $list = $settings['black_list'] ) && FALSE !== strpos( $list, $validate['code'] ) )
314
+ return $validate + array( 'result' => 'blocked' ); // can't overwrite existing result
315
+ }
316
+
317
+ return $validate + array( 'result' => 'passed' ); // can't overwrite existing result
318
+ }
319
+
320
+ /**
321
+ * Send response header with http status code and reason.
322
+ *
323
+ */
324
+ public function send_response( $hook, $settings ) {
325
+ require_once ABSPATH . WPINC . '/functions.php'; // for get_status_header_desc() @since 2.3.0
326
+
327
+ // prevent caching (WP Super Cache, W3TC, Wordfence, Comet Cache)
328
+ if ( ! defined( 'DONOTCACHEPAGE' ) )
329
+ define( 'DONOTCACHEPAGE', TRUE );
330
+
331
+ $code = (int )apply_filters( self::PLUGIN_NAME . '-'.$hook.'-status', $settings['response_code'] );
332
+ $mesg = (string)apply_filters( self::PLUGIN_NAME . '-'.$hook.'-reason', $settings['response_msg' ] ? $settings['response_msg'] : get_status_header_desc( $code ) );
333
+
334
+ nocache_headers(); // Set the headers to prevent caching for the different browsers.
335
+
336
+ if ( defined( 'XMLRPC_REQUEST' ) && 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
337
+ status_header( 405 );
338
+ header( 'Content-Type: text/plain' );
339
+ die( 'XML-RPC server accepts POST requests only.' );
340
+ }
341
+
342
+ switch ( (int)substr( (string)$code, 0, 1 ) ) {
343
+ case 2: // 2xx Success (HTTP header injection should be avoided)
344
+ header( 'Refresh: 0; url=' . esc_url_raw( $settings['redirect_uri'] ? $settings['redirect_uri'] : home_url( '/' ) ), TRUE, $code ); // @since 2.8
345
+ exit;
346
+
347
+ case 3: // 3xx Redirection (HTTP header injection should be avoided)
348
+ IP_Geo_Block_Util::safe_redirect( esc_url_raw( $settings['redirect_uri'] ? $settings['redirect_uri'] : home_url( '/' ) ), $code ); // @since 2.8
349
+ exit;
350
+
351
+ default: // 4xx Client Error, 5xx Server Error
352
+ status_header( $code ); // @since 2.0.0
353
+
354
+ // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag
355
+ 'public' !== $hook and header( 'X-Robots-Tag: noindex, nofollow', FALSE );
356
+
357
+ if ( function_exists( 'trackback_response' ) )
358
+ trackback_response( $code, IP_Geo_Block_Util::kses( $mesg ) ); // @since 0.71
359
+
360
+ // Show human readable page
361
+ elseif ( ! defined( 'DOING_AJAX' ) && ! defined( 'XMLRPC_REQUEST' ) ) {
362
+ $hook = IP_Geo_Block_Util::may_be_logged_in() && 'admin' === $this->target_type;
363
+ FALSE !== ( @include get_stylesheet_directory() .'/'.$code.'.php' ) or // child theme
364
+ FALSE !== ( @include get_template_directory() .'/'.$code.'.php' ) or // parent theme
365
+ wp_die( // get_dashboard_url() @since 3.1.0
366
+ IP_Geo_Block_Util::kses( $mesg ) . ( $hook ? "\n<p><a rel='nofollow' href='" . esc_url( get_dashboard_url() ) . "'>&laquo; " . __( 'Dashboard' ) . "</a></p>" : '' ),
367
+ '', array( 'response' => $code, 'back_link' => ! $hook )
368
+ );
369
+ }
370
+ exit;
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Validate ip address.
376
+ *
377
+ * @param string $hook a name to identify action hook applied in this call.
378
+ * @param array $settings option settings
379
+ * @param boolean $die send http response and die if validation fails
380
+ */
381
+ public function validate_ip( $hook, $settings, $block = TRUE, $die = TRUE, $auth = TRUE ) {
382
+ // set IP address to be validated
383
+ $ips = array( self::get_ip_address() );
384
+
385
+ // pick up all the IPs in HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP and etc.
386
+ foreach ( explode( ',', $settings['validation']['proxy'] ) as $var ) {
387
+ if ( isset( $_SERVER[ $var ] ) ) {
388
+ foreach ( explode( ',', $_SERVER[ $var ] ) as $ip ) {
389
+ if ( ! in_array( $ip = trim( $ip ), $ips, TRUE ) && filter_var( $ip, FILTER_VALIDATE_IP ) ) {
390
+ array_unshift( $ips, $ip );
391
+ }
392
+ }
393
+ }
394
+ }
395
+
396
+ // register auxiliary validation functions
397
+ $var = self::PLUGIN_NAME . '-' . $hook;
398
+ add_filter( $var, array( $this, 'check_fail' ), 9, 2 );
399
+ $auth and add_filter( $var, array( $this, 'check_auth' ), 8, 2 );
400
+ $settings['extra_ips'] = apply_filters( self::PLUGIN_NAME . '-extra-ips', $settings['extra_ips'], $hook );
401
+ $settings['extra_ips']['white_list'] and add_filter( $var, array( $this, 'check_ips_white' ), 7, 2 );
402
+ $settings['extra_ips']['black_list'] and add_filter( $var, array( $this, 'check_ips_black' ), 7, 2 );
403
+
404
+ // make valid provider name list
405
+ $providers = IP_Geo_Block_Provider::get_valid_providers( $settings['providers'] );
406
+
407
+ // apply custom filter for validation
408
+ // @example add_filter( 'ip-geo-block-$hook', 'my_validation', 10, 2 );
409
+ // @param $validate = array(
410
+ // 'ip' => $ip, /* validated ip address */
411
+ // 'auth' => $auth, /* authenticated or not */
412
+ // 'code' => $code, /* country code or reason of rejection */
413
+ // 'result' => $result, /* 'passed', 'blocked' */
414
+ // );
415
+ foreach ( $ips as $this->remote_addr ) {
416
+ $validate = self::_get_geolocation( $this->remote_addr, $settings, $providers );
417
+ $validate = apply_filters( $var, $validate, $settings );
418
+
419
+ // if no 'result' then validate ip address by country
420
+ if ( empty( $validate['result'] ) )
421
+ $validate = self::validate_country( $hook, $validate, $settings, $block );
422
+
423
+ // if one of IPs is blocked then stop
424
+ if ( 'passed' !== $validate['result'] )
425
+ break;
426
+ }
427
+
428
+ if ( $auth ) {
429
+ // record log (0:no, 1:blocked, 2:passed, 3:unauth, 4:auth, 5:all)
430
+ $var = (int)apply_filters( self::PLUGIN_NAME . '-record-logs', $settings['validation']['reclogs'], $hook, $validate );
431
+ $block = ( 'passed' !== $validate['result'] );
432
+ if ( ( 1 === $var && $block ) || // blocked
433
+ ( 2 === $var && ! $block ) || // passed
434
+ ( 3 === $var && ! $validate['auth'] ) || // unauthenticated
435
+ ( 4 === $var && $validate['auth'] ) || // authenticated
436
+ ( 5 === $var ) ) { // all
437
+ IP_Geo_Block_Logs::record_logs( $hook, $validate, $settings );
438
+ }
439
+
440
+ // update cache
441
+ IP_Geo_Block_API_Cache::update_cache( $hook, $validate, $settings );
442
+
443
+ // update statistics
444
+ if ( $settings['save_statistics'] )
445
+ IP_Geo_Block_Logs::update_stat( $hook, $validate, $settings );
446
+
447
+ // send response code to refuse
448
+ if ( $block && $die )
449
+ $this->send_response( $hook, $settings );
450
+ }
451
+
452
+ return $validate;
453
+ }
454
+
455
+ /**
456
+ * Validate on comment.
457
+ *
458
+ */
459
+ public function validate_comment( $comment = NULL ) {
460
+ // check comment type if it comes form wp-includes/wp_new_comment()
461
+ if ( ! is_array( $comment ) || in_array( $comment['comment_type'], array( 'trackback', 'pingback' ), TRUE ) )
462
+ $this->validate_ip( 'comment', self::get_option() );
463
+
464
+ return $comment;
465
+ }
466
+
467
+ public function validate_front( $can_access = TRUE ) {
468
+ $validate = $this->validate_ip( 'comment', self::get_option(), TRUE, FALSE );
469
+ return ( 'passed' === $validate['result'] ? $can_access : FALSE );
470
+ }
471
+
472
+ /**
473
+ * Validate on xmlrpc.
474
+ *
475
+ */
476
+ public function validate_xmlrpc() {
477
+ $settings = self::get_option();
478
+
479
+ if ( 2 === (int)$settings['validation']['xmlrpc'] ) // Completely close
480
+ add_filter( self::PLUGIN_NAME . '-xmlrpc', array( $this, 'close_xmlrpc' ), 6, 2 );
481
+
482
+ else // wp-includes/class-wp-xmlrpc-server.php @since 3.5.0
483
+ add_filter( 'xmlrpc_login_error', array( $this, 'auth_fail' ), $settings['priority'] );
484
+
485
+ $this->validate_ip( 'xmlrpc', $settings );
486
+ }
487
+
488
+ public function close_xmlrpc( $validate, $settings ) {
489
+ return $validate + array( 'result' => 'closed' ); // can't overwrite existing result
490
+ }
491
+
492
+ /**
493
+ * Validate on login.
494
+ *
495
+ */
496
+ public function validate_login() {
497
+ // parse action
498
+ $action = isset( $_GET['key'] ) ?
499
+ 'resetpass' : ( isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'login' );
500
+
501
+ if ( 'retrievepassword' === $action )
502
+ $action = 'lostpassword';
503
+ elseif ( 'rp' === $action )
504
+ $action = 'resetpass';
505
+
506
+ $settings = self::get_option();
507
+ $list = &$settings['login_action'];
508
+
509
+ // the same rule should be applied to login and logout
510
+ ! empty( $list['login'] ) and $list['logout'] = TRUE;
511
+
512
+ // wp-includes/pluggable.php @since 2.5.0
513
+ add_action( 'wp_login_failed', array( $this, 'auth_fail' ), $settings['priority'] );
514
+
515
+ // enables to skip validation of country on login/out except BuddyPress signup
516
+ $this->validate_ip( 'login', $settings, ! empty( $list[ $action ] ) || 'bp_' === substr( current_filter(), 0, 3 ) );
517
+ }
518
+
519
+ /**
520
+ * Validate in admin area.
521
+ *
522
+ */
523
+ public function validate_admin() {
524
+ // if there's no action parameter but something is specified
525
+ $settings = self::get_option();
526
+ $action = isset( $_REQUEST['task' ] ) ? 'task' : 'action';
527
+ $action = isset( $_REQUEST[$action] ) ? $_REQUEST[$action] : NULL;
528
+ $page = isset( $_REQUEST['page' ] ) ? $_REQUEST['page' ] : NULL;
529
+
530
+ switch ( $this->pagenow ) {
531
+ case 'admin-ajax.php':
532
+ // if the request has an action for no privilege user, skip WP-ZEP
533
+ $zep = ! has_action( 'wp_ajax_nopriv_'.$action );
534
+ $type = (int)$settings['validation']['ajax'];
535
+ break;
536
+
537
+ case 'admin-post.php':
538
+ // if the request has an action for no privilege user, skip WP-ZEP
539
+ $zep = ! has_action( 'admin_post_nopriv' . ($action ? '_'.$action : '') );
540
+ $type = (int)$settings['validation']['ajax'];
541
+ break;
542
+
543
+ default:
544
+ // if the request has no page and no action, skip WP-ZEP
545
+ $zep = ( $page || $action ) ? TRUE : FALSE;
546
+ $type = (int)$settings['validation']['admin'];
547
+ }
548
+
549
+ // list of request for specific action or page to bypass WP-ZEP
550
+ $list = array_merge(
551
+ apply_filters( self::PLUGIN_NAME . '-bypass-admins', $settings['exception']['admin'] ),
552
+ array( 'save-widget', 'wordfence_testAjax', 'wordfence_doScan', 'wp-compression-test', // wp-admin/includes/template.php
553
+ 'upload-attachment', 'imgedit-preview', 'bp_avatar_upload', 'GOTMLS_logintime', // pluploader won't fire an event in "Media Library"
554
+ 'jetpack', 'authorize', 'jetpack_modules', 'atd_settings', 'bulk-activate', 'bulk-deactivate', // jetpack page & action
555
+ )
556
+ );
557
+
558
+ $in_action = in_array( $action, $list, TRUE );
559
+ $in_page = in_array( $page, $list, TRUE );
560
+
561
+ // combination with vulnerable keys should be prevented to bypass WP-ZEP
562
+ if ( ( ( $action xor $page ) && ( ! $in_action and ! $in_page ) ) ||
563
+ ( ( $action and $page ) && ( ! $in_action or ! $in_page ) ) ) {
564
+ if ( ( 2 & $type ) && $zep ) {
565
+ // redirect if valid nonce in referer, otherwise register WP-ZEP (2: WP-ZEP)
566
+ IP_Geo_Block_Util::trace_nonce( self::PLUGIN_NAME . '-auth-nonce' );
567
+ add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_nonce' ), 5, 2 );
568
+ }
569
+
570
+ // register validation of malicious signature (except in the comment and post)
571
+ if ( ! IP_Geo_Block_Util::may_be_logged_in() || ! in_array( $this->pagenow, array( 'comment.php', 'post.php' ), TRUE ) )
572
+ add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_signature' ), 6, 2 );
573
+ }
574
+
575
+ // validate country by IP address (1: Block by country)
576
+ $this->validate_ip( 'admin', $settings, 1 & $type );
577
+ }
578
+
579
+ /**
580
+ * Validate in plugins/themes area.
581
+ *
582
+ */
583
+ public function validate_direct() {
584
+ // analyze target in wp-includes, wp-content/(plugins|themes|language|uploads)
585
+ $path = preg_quote( self::$wp_path[ $type = $this->target_type ], '/' );
586
+ $target = ( 'plugins' === $type || 'themes' === $type ? '[^\?\&\/]*' : '[^\?\&]*' );
587
+
588
+ preg_match( "/($path)($target)/", $this->request_uri, $target );
589
+ $target = empty( $target[2] ) ? $target[1] : $target[2];
590
+
591
+ // set validation type by target (0: Bypass, 1: Block by country, 2: WP-ZEP)
592
+ $settings = self::get_option();
593
+ $path = apply_filters( self::PLUGIN_NAME . "-bypass-{$type}", $settings['exception'][ $type ] );
594
+ $type = (int)$settings['validation'][ $type ];
595
+
596
+ if ( ! in_array( $target, $path, TRUE ) ) {
597
+ if ( 2 & $type ) {
598
+ // redirect if valid nonce in referer, otherwise register WP-ZEP (2: WP-ZEP)
599
+ IP_Geo_Block_Util::trace_nonce( self::PLUGIN_NAME . '-auth-nonce' );
600
+ add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_nonce' ), 5, 2 );
601
+ }
602
+
603
+ // register validation of malicious signature
604
+ if ( ! IP_Geo_Block_Util::may_be_logged_in() )
605
+ add_filter( self::PLUGIN_NAME . '-admin', array( $this, 'check_signature' ), 6, 2 );
606
+ }
607
+
608
+ // validate country by IP address (1: Block by country)
609
+ $validate = $this->validate_ip( 'admin', $settings, 1 & $type );
610
+
611
+ // if the validation is successful, execute the requested uri via rewrite.php
612
+ if ( class_exists( 'IP_Geo_Block_Rewrite' ) )
613
+ IP_Geo_Block_Rewrite::exec( $this, $validate, $settings );
614
+ }
615
+
616
+ /**
617
+ * Auxiliary validation functions
618
+ *
619
+ */
620
+ public function auth_fail( $something = NULL ) {
621
+ // Count up a number of fails when authentication is failed
622
+ if ( $cache = IP_Geo_Block_API_Cache::get_cache( $this->remote_addr ) ) {
623
+ $validate = self::make_validation( $this->remote_addr, array(
624
+ 'code' => $cache['code'],
625
+ 'fail' => TRUE,
626
+ 'result' => 'failed',
627
+ 'provider' => 'Cache',
628
+ ) );
629
+
630
+ $settings = self::get_option();
631
+
632
+ if ( $cache['fail'] > max( 0, (int)$settings['login_fails'] ) )
633
+ $validate['result'] = 'limited';
634
+
635
+ // validate xmlrpc system.multicall
636
+ elseif ( defined( 'XMLRPC_REQUEST' ) && FALSE !== stripos( file_get_contents( 'php://input' ), 'system.multicall' ) )
637
+ $validate['result'] = 'multi';
638
+
639
+ $cache = IP_Geo_Block_API_Cache::update_cache( 'login', $validate, $settings ); // count up 'fail'
640
+
641
+ // (1) blocked, (3) unauthenticated, (5) all
642
+ if ( 1 & (int)$settings['validation']['reclogs'] )
643
+ IP_Geo_Block_Logs::record_logs( 'login', $validate, $settings );
644
+
645
+ // send response code to refuse immediately
646
+ if ( 'failed' !== $validate['result'] ) {
647
+ if ( $settings['save_statistics'] )
648
+ IP_Geo_Block_Logs::update_stat( 'login', $validate, $settings );
649
+
650
+ $this->send_response( 'login', $settings );
651
+ }
652
+ }
653
+
654
+ return $something; // pass through
655
+ }
656
+
657
+ public function check_fail( $validate, $settings ) {
658
+ // check if number of fails reaches the limit. can't overwrite existing result.
659
+ $cache = IP_Geo_Block_API_Cache::get_cache( $validate['ip'] );
660
+ return $cache && $cache['fail'] >= max( 0, (int)$settings['login_fails'] ) ? $validate + array( 'result' => 'limited' ) : $validate;
661
+ }
662
+
663
+ public function check_auth( $validate, $settings ) {
664
+ // authentication should be prior to validation of country
665
+ return $validate['auth'] ? $validate + array( 'result' => 'passed' ) : $validate; // can't overwrite existing result
666
+ }
667
+
668
+ public function check_nonce( $validate, $settings ) {
669
+ // should be passed when nonce is valid. can't overwrite existing result
670
+ $nonce = IP_Geo_Block_Util::retrieve_nonce( $action = self::PLUGIN_NAME . '-auth-nonce' );
671
+ return $validate + array( 'result' => IP_Geo_Block_Util::verify_nonce( $nonce, $action ) ? 'passed' : 'wp-zep' );
672
+ }
673
+
674
+ public function check_signature( $validate, $settings ) {
675
+ $score = 0.0;
676
+ $query = strtolower( urldecode( serialize( array_values( $_GET + $_POST ) ) ) );
677
+
678
+ foreach ( IP_Geo_Block_Util::multiexplode( array( ",", "\n" ), $settings['signature'] ) as $sig ) {
679
+ $val = explode( ':', $sig, 2 );
680
+
681
+ if ( ( $sig = trim( $val[0] ) ) && FALSE !== strpos( $query, $sig ) ) {
682
+ if ( ( $score += ( empty( $val[1] ) ? 1.0 : (float)$val[1] ) ) > 0.99 )
683
+ return $validate + array( 'result' => 'badsig' ); // can't overwrite existing result
684
+ }
685
+ }
686
+
687
+ return $validate;
688
+ }
689
+
690
+ /**
691
+ * Verify specific ip addresses with CIDR.
692
+ *
693
+ */
694
+ public function check_ips_white( $validate, $settings ) {
695
+ return $this->check_ips( $validate, $settings['extra_ips']['white_list'], 0 );
696
+ }
697
+
698
+ public function check_ips_black( $validate, $settings ) {
699
+ return $this->check_ips( $validate, $settings['extra_ips']['black_list'], 1 );
700
+ }
701
+
702
+ private function check_ips( $validate, $ips, $which ) {
703
+ if ( filter_var( $ip = $validate['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
704
+ require_once IP_GEO_BLOCK_PATH . 'includes/Net/IPv4.php';
705
+
706
+ foreach ( IP_Geo_Block_Util::multiexplode( array( ",", "\n" ), $ips ) as $i ) {
707
+ $j = explode( '/', $i, 2 );
708
+
709
+ if ( filter_var( $j[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) &&
710
+ Net_IPv4::ipInNetwork( $ip, isset( $j[1] ) ? $i : $i.'/32' ) )
711
+ // can't overwrite existing result
712
+ return $validate + array( 'result' => $which ? 'extra' : 'passed' );
713
+ }
714
+ }
715
+
716
+ elseif ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
717
+ require_once IP_GEO_BLOCK_PATH . 'includes/Net/IPv6.php';
718
+
719
+ foreach ( IP_Geo_Block_Util::multiexplode( array( ",", "\n" ), $ips ) as $i ) {
720
+ $j = explode( '/', $i, 2 );
721
+
722
+ if ( filter_var( $j[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) &&
723
+ Net_IPv6::isInNetmask( $ip, isset( $j[1] ) ? $i : $i.'/128' ) )
724
+ // can't overwrite existing result
725
+ return $validate + array( 'result' => $which ? 'extra' : 'passed' );
726
+ }
727
+ }
728
+
729
+ return $validate;
730
+ }
731
+
732
+ /**
733
+ * Validate on public facing pages.
734
+ *
735
+ */
736
+ public function validate_public() {
737
+ $settings = self::get_option();
738
+ $public = &$settings['public'];
739
+
740
+ // avoid redirection loop
741
+ if ( $settings['response_code'] < 400 && IP_Geo_Block_Util::compare_url( $_SERVER['REQUEST_URI'], $settings['redirect_uri'] ? $settings['redirect_uri'] : home_url( '/' ) ) )
742
+ return; // do not block
743
+
744
+ if ( $public['target_rule'] ) {
745
+ // postpone validation until 'wp' fires
746
+ if ( ! did_action( 'wp' ) ) {
747
+ add_action( 'wp', array( $this, 'validate_public' ) );
748
+ return;
749
+ }
750
+
751
+ // register filter hook to check pages and post types
752
+ add_filter( self::PLUGIN_NAME . '-public', array( $this, 'check_page' ), 10, 2 );
753
+ }
754
+
755
+ // replace "Validation rule settings"
756
+ if ( -1 !== (int)$public['matching_rule'] ) {
757
+ $settings['matching_rule'] = $public['matching_rule'];
758
+ $settings['white_list' ] = $public['white_list' ];
759
+ $settings['black_list' ] = $public['black_list' ];
760
+ }
761
+
762
+ // retrieve IP address of visitor via proxy services
763
+ add_filter( self::PLUGIN_NAME . '-ip-addr', array( $this, 'get_proxy_ip' ), 20, 1 );
764
+
765
+ // validate undesired user agent
766
+ add_filter( self::PLUGIN_NAME . '-public', array( $this, 'check_bots' ), 6, 2 );
767
+
768
+ // validate country by IP address (block: true, die: false)
769
+ $this->validate_ip( 'public', $settings, TRUE, ! $public['simulate'] );
770
+ }
771
+
772
+ public function get_proxy_ip( $ip ) {
773
+ if ( isset( $_SERVER['HTTP_VIA'] ) && FALSE !== strpos( $_SERVER['HTTP_VIA'], 'Chrome-Compression-Proxy' ) && isset( $_SERVER['HTTP_FORWARDED'] ) ) {
774
+ // require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-lkup.php';
775
+ // if ( FALSE !== strpos( 'google', IP_Geo_Block_Lkup::gethostbyaddr( $ip ) ) )
776
+ $proxy = preg_replace( '/^for=.*?([a-f\d\.:]+).*$/', '$1', $_SERVER['HTTP_FORWARDED'] );
777
+ }
778
+
779
+ return empty( $proxy ) ? $ip : $proxy;
780
+ }
781
+
782
+ public function check_page( $validate, $settings ) {
783
+ global $post;
784
+ $public = &$settings['public'];
785
+
786
+ if ( $post ) {
787
+ // check page
788
+ if ( isset( $post->post_name ) && isset( $public['target_pages'][ $post->post_name ] ) )
789
+ return $validate; // block by country
790
+
791
+ // check post type (this would not block top page)
792
+ $keys = array_keys( $public['target_posts'] );
793
+ if ( ! empty( $keys ) && is_singular( $keys ) )
794
+ return $validate; // block by country
795
+
796
+ // check category (single page or category archive)
797
+ $keys = array_keys( $public['target_cates'] );
798
+ if ( ! empty( $keys ) && in_category( $keys ) && ( is_single() || is_category() ) )
799
+ return $validate; // block by country
800
+
801
+ // check tag (single page or tag archive)
802
+ $keys = array_keys( $public['target_tags'] );
803
+ if ( ! empty( $keys ) && has_tag( $keys ) && ( is_single() || is_tag() ) )
804
+ return $validate; // block by country
805
+ }
806
+
807
+ return $validate + array( 'result' => 'passed' ); // provide content
808
+ }
809
+
810
+ public function check_bots( $validate, $settings ) {
811
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-lkup.php';
812
+
813
+ // get the name of host (from the cache if exists)
814
+ if ( empty( $validate['host'] ) && FALSE !== strpos( $settings['public']['ua_list'], 'HOST' ) )
815
+ $validate['host'] = IP_Geo_Block_Lkup::gethostbyaddr( $validate['ip'] );
816
+
817
+ // check requested url
818
+ $is_feed = IP_Geo_Block_Lkup::is_feed( $this->request_uri );
819
+ $u_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '';
820
+ $referer = isset( $_SERVER['HTTP_REFERER' ] ) ? $_SERVER['HTTP_REFERER' ] : '';
821
+
822
+ foreach ( IP_Geo_Block_Util::multiexplode( array( ",", "\n" ), $settings['public']['ua_list'] ) as $pat ) {
823
+ list( $name, $code ) = array_pad( IP_Geo_Block_Util::multiexplode( array( ':', '#' ), $pat ), 2, '' );
824
+
825
+ if ( $name && ( '*' === $name || FALSE !== strpos( $u_agent, $name ) ) ) {
826
+ $which = ( FALSE === strpos( $pat, ':' ) ); // 0: pass (':'), 1: block ('#')
827
+ $not = ( '!' === $code[0] ); // 0: positive, 1: negative
828
+ $code = ( $not ? substr( $code, 1 ) : $code ); // qualification identifier
829
+
830
+ if ( 'FEED' === $code ) {
831
+ if ( $not xor $is_feed )
832
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
833
+ }
834
+
835
+ elseif ( 'HOST' === $code ) {
836
+ if ( $not xor $validate['host'] !== $validate['ip'] )
837
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
838
+ }
839
+
840
+ elseif ( 0 === strncmp( 'HOST=', $code, 5 ) ) {
841
+ if ( $not xor FALSE !== strpos( $validate['host'], substr( $code, 5 ) ) )
842
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
843
+ }
844
+
845
+ elseif ( 0 === strncmp( 'REF=', $code, 4 ) ) {
846
+ if ( $not xor FALSE !== strpos( $referer, substr( $code, 4 ) ) )
847
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
848
+ }
849
+
850
+ elseif ( '*' === $code || 2 === strlen( $code ) ) {
851
+ if ( $not xor ( '*' === $code || $validate['code'] === $code ) )
852
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
853
+ }
854
+
855
+ elseif ( preg_match( '!^[a-f\d\.:/]+$!', $code ) ) {
856
+ $name = $this->check_ips( $validate, $code, $which );
857
+ if ( $not xor isset( $name['result'] ) )
858
+ return $validate + array( 'result' => $which ? 'blocked' : 'passed' );
859
+ }
860
+ }
861
+ }
862
+
863
+ return $validate;
864
+ }
865
+
866
+ /**
867
+ * Handlers of cron job
868
+ *
869
+ */
870
+ public function update_database( $immediate = FALSE ) {
871
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-cron.php';
872
+ return IP_Geo_Block_Cron::exec_job( $immediate );
873
+ }
874
+
875
+ public function exec_cache_gc() {
876
+ require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-cron.php';
877
+ IP_Geo_Block_Cron::exec_cache_gc( self::get_option() );
878
+ }
879
+
880
+ }
database/index.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php
2
+ // Silence is golden.
3
+ ?>
includes/Net/DNS2.php ADDED
@@ -0,0 +1,1427 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /*
53
+ * register the auto-load function
54
+ *
55
+ */
56
+ spl_autoload_register('Net_DNS2::autoload');
57
+
58
+ /**
59
+ * This is the base class for the Net_DNS2_Resolver and Net_DNS2_Updater
60
+ * classes.
61
+ *
62
+ * @category Networking
63
+ * @package Net_DNS2
64
+ * @author Mike Pultz <mike@mikepultz.com>
65
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
66
+ * @link http://pear.php.net/package/Net_DNS2
67
+ * @see Net_DNS2_Resolver, Net_DNS2_Updater
68
+ *
69
+ */
70
+ class Net_DNS2
71
+ {
72
+ /*
73
+ * the current version of this library
74
+ */
75
+ const VERSION = '1.4.2';
76
+
77
+ /*
78
+ * the default path to a resolv.conf file
79
+ */
80
+ const RESOLV_CONF = '/etc/resolv.conf';
81
+
82
+ /*
83
+ * override options from the resolv.conf file
84
+ *
85
+ * if this is set, then certain values from the resolv.conf file will override
86
+ * local settings. This is disabled by default to remain backwards compatible.
87
+ *
88
+ */
89
+ public $use_resolv_options = false;
90
+
91
+ /*
92
+ * use TCP only (true/false)
93
+ */
94
+ public $use_tcp = false;
95
+
96
+ /*
97
+ * DNS Port to use (53)
98
+ */
99
+ public $dns_port = 53;
100
+
101
+ /*
102
+ * the ip/port for use as a local socket
103
+ */
104
+ public $local_host = '';
105
+ public $local_port = 0;
106
+
107
+ /*
108
+ * timeout value for socket connections
109
+ */
110
+ public $timeout = 5;
111
+
112
+ /*
113
+ * randomize the name servers list
114
+ */
115
+ public $ns_random = false;
116
+
117
+ /*
118
+ * default domains
119
+ */
120
+ public $domain = '';
121
+
122
+ /*
123
+ * domain search list - not actually used right now
124
+ */
125
+ public $search_list = array();
126
+
127
+ /*
128
+ * enable cache; either "shared", "file" or "none"
129
+ */
130
+ public $cache_type = 'none';
131
+
132
+ /*
133
+ * file name to use for shared memory segment or file cache
134
+ */
135
+ public $cache_file = '/tmp/net_dns2.cache';
136
+
137
+ /*
138
+ * the max size of the cache file (in bytes)
139
+ */
140
+ public $cache_size = 50000;
141
+
142
+ /*
143
+ * the method to use for storing cache data; either "serialize" or "json"
144
+ *
145
+ * json is faster, but can't remember the class names (everything comes back
146
+ * as a "stdClass Object"; all the data is the same though. serialize is
147
+ * slower, but will have all the class info.
148
+ *
149
+ * defaults to 'serialize'
150
+ */
151
+ public $cache_serializer = 'serialize';
152
+
153
+ /*
154
+ * by default, according to RFC 1034
155
+ *
156
+ * CNAME RRs cause special action in DNS software. When a name server
157
+ * fails to find a desired RR in the resource set associated with the
158
+ * domain name, it checks to see if the resource set consists of a CNAME
159
+ * record with a matching class. If so, the name server includes the CNAME
160
+ * record in the response and restarts the query at the domain name
161
+ * specified in the data field of the CNAME record.
162
+ *
163
+ * this can cause "unexpected" behavious, since i'm sure *most* people
164
+ * don't know DNS does this; there may be cases where Net_DNS2 returns a
165
+ * positive response, even though the hostname the user looked up did not
166
+ * actually exist.
167
+ *
168
+ * strict_query_mode means that if the hostname that was looked up isn't
169
+ * actually in the answer section of the response, Net_DNS2 will return an
170
+ * empty answer section, instead of an answer section that could contain
171
+ * CNAME records.
172
+ *
173
+ */
174
+ public $strict_query_mode = false;
175
+
176
+ /*
177
+ * if we should set the recursion desired bit to 1 or 0.
178
+ *
179
+ * by default this is set to true, we want the DNS server to perform a recursive
180
+ * request. If set to false, the RD bit will be set to 0, and the server will
181
+ * not perform recursion on the request.
182
+ */
183
+ public $recurse = true;
184
+
185
+ /*
186
+ * request DNSSEC values, by setting the DO flag to 1; this actually makes
187
+ * the resolver add a OPT RR to the additional section, and sets the DO flag
188
+ * in this RR to 1
189
+ *
190
+ */
191
+ public $dnssec = false;
192
+
193
+ /*
194
+ * set the DNSSEC AD (Authentic Data) bit on/off; the AD bit on the request
195
+ * side was previously undefined, and resolvers we instructed to always clear
196
+ * the AD bit when sending a request.
197
+ *
198
+ * RFC6840 section 5.7 defines setting the AD bit in the query as a signal to
199
+ * the server that it wants the value of the AD bit, without needed to request
200
+ * all the DNSSEC data via the DO bit.
201
+ *
202
+ */
203
+ public $dnssec_ad_flag = false;
204
+
205
+ /*
206
+ * set the DNSSEC CD (Checking Disabled) bit on/off; turning this off, means
207
+ * that the DNS resolver will perform it's own signature validation- so the DNS
208
+ * servers simply pass through all the details.
209
+ *
210
+ */
211
+ public $dnssec_cd_flag = false;
212
+
213
+ /*
214
+ * the EDNS(0) UDP payload size to use when making DNSSEC requests
215
+ * see RFC 4035 section 4.1 - EDNS Support.
216
+ *
217
+ * there is some different ideas on the suggest size to supprt; but it seems to
218
+ * be "at least 1220 bytes, but SHOULD support 4000 bytes.
219
+ *
220
+ * we'll just support 4000
221
+ *
222
+ */
223
+ public $dnssec_payload_size = 4000;
224
+
225
+ /*
226
+ * the last exeception that was generated
227
+ */
228
+ public $last_exception = null;
229
+
230
+ /*
231
+ * the list of exceptions by name server
232
+ */
233
+ public $last_exception_list = array();
234
+
235
+ /*
236
+ * name server list
237
+ */
238
+ public $nameservers = array();
239
+
240
+ /*
241
+ * local sockets
242
+ */
243
+ protected $sock = array('udp' => array(), 'tcp' => array());
244
+
245
+ /*
246
+ * if the socket extension is loaded
247
+ */
248
+ protected $sockets_enabled = false;
249
+
250
+ /*
251
+ * the TSIG or SIG RR object for authentication
252
+ */
253
+ protected $auth_signature = null;
254
+
255
+ /*
256
+ * the shared memory segment id for the local cache
257
+ */
258
+ protected $cache = null;
259
+
260
+ /*
261
+ * internal setting for enabling cache
262
+ */
263
+ protected $use_cache = false;
264
+
265
+ /**
266
+ * Constructor - base constructor for the Resolver and Updater
267
+ *
268
+ * @param mixed $options array of options or null for none
269
+ *
270
+ * @throws Net_DNS2_Exception
271
+ * @access public
272
+ *
273
+ */
274
+ public function __construct(array $options = null)
275
+ {
276
+ //
277
+ // check for the sockets extension; we no longer support the sockets library under
278
+ // windows- there have been too many errors related to sockets under windows-
279
+ // specifically inconsistent socket defines between versions of windows-
280
+ //
281
+ // and since I can't seem to find a way to get the actual windows version, it
282
+ // doesn't seem fixable in the code.
283
+ //
284
+ if ( (extension_loaded('sockets') == true) && (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') ) {
285
+
286
+ $this->sockets_enabled = true;
287
+ }
288
+
289
+ //
290
+ // load any options that were provided
291
+ //
292
+ if (!empty($options)) {
293
+
294
+ foreach ($options as $key => $value) {
295
+
296
+ if ($key == 'nameservers') {
297
+
298
+ $this->setServers($value);
299
+ } else {
300
+
301
+ $this->$key = $value;
302
+ }
303
+ }
304
+ }
305
+
306
+ //
307
+ // if we're set to use the local shared memory cache, then
308
+ // make sure it's been initialized
309
+ //
310
+ switch($this->cache_type) {
311
+ case 'shared':
312
+ if (extension_loaded('shmop')) {
313
+
314
+ $this->cache = new Net_DNS2_Cache_Shm;
315
+ $this->use_cache = true;
316
+ } else {
317
+
318
+ throw new Net_DNS2_Exception(
319
+ 'shmop library is not available for cache',
320
+ Net_DNS2_Lookups::E_CACHE_SHM_UNAVAIL
321
+ );
322
+ }
323
+ break;
324
+ case 'file':
325
+
326
+ $this->cache = new Net_DNS2_Cache_File;
327
+ $this->use_cache = true;
328
+
329
+ break;
330
+ case 'none':
331
+ $this->use_cache = false;
332
+ break;
333
+ default:
334
+
335
+ throw new Net_DNS2_Exception(
336
+ 'un-supported cache type: ' . $this->cache_type,
337
+ Net_DNS2_Lookups::E_CACHE_UNSUPPORTED
338
+ );
339
+ }
340
+ }
341
+
342
+ /**
343
+ * autoload call-back function; used to auto-load classes
344
+ *
345
+ * @param string $name the name of the class
346
+ *
347
+ * @return void
348
+ * @access public
349
+ *
350
+ */
351
+ static public function autoload($name)
352
+ {
353
+ //
354
+ // only auto-load our classes
355
+ //
356
+ if (strncmp($name, 'Net_DNS2', 8) == 0) {
357
+
358
+ include str_replace('_', '/', $name) . '.php';
359
+ }
360
+
361
+ return;
362
+ }
363
+
364
+ /**
365
+ * sets the name servers to be used
366
+ *
367
+ * @param mixed $nameservers either an array of name servers, or a file name
368
+ * to parse, assuming it's in the resolv.conf format
369
+ *
370
+ * @return boolean
371
+ * @throws Net_DNS2_Exception
372
+ * @access public
373
+ *
374
+ */
375
+ public function setServers($nameservers)
376
+ {
377
+ //
378
+ // if it's an array, then use it directly
379
+ //
380
+ // otherwise, see if it's a path to a resolv.conf file and if so, load it
381
+ //
382
+ if (is_array($nameservers)) {
383
+
384
+ $this->nameservers = $nameservers;
385
+
386
+ } else {
387
+
388
+ //
389
+ // temporary list of name servers; do it this way rather than just
390
+ // resetting the local nameservers value, just incase an exception
391
+ // is thrown here; this way we might avoid ending up with an empty
392
+ // namservers list.
393
+ //
394
+ $ns = array();
395
+
396
+ //
397
+ // check to see if the file is readable
398
+ //
399
+ if (is_readable($nameservers) === true) {
400
+
401
+ $data = file_get_contents($nameservers);
402
+ if ($data === false) {
403
+ throw new Net_DNS2_Exception(
404
+ 'failed to read contents of file: ' . $nameservers,
405
+ Net_DNS2_Lookups::E_NS_INVALID_FILE
406
+ );
407
+ }
408
+
409
+ $lines = explode("\n", $data);
410
+
411
+ foreach ($lines as $line) {
412
+
413
+ $line = trim($line);
414
+
415
+ //
416
+ // ignore empty lines, and lines that are commented out
417
+ //
418
+ if ( (strlen($line) == 0)
419
+ || ($line[0] == '#')
420
+ || ($line[0] == ';')
421
+ ) {
422
+ continue;
423
+ }
424
+
425
+ //
426
+ // ignore lines with no spaces in them.
427
+ //
428
+ if (strpos($line, ' ') === false) {
429
+ continue;
430
+ }
431
+
432
+ list($key, $value) = preg_split('/\s+/', $line, 2);
433
+
434
+ $key = trim(strtolower($key));
435
+ $value = trim(strtolower($value));
436
+
437
+ switch($key) {
438
+ case 'nameserver':
439
+
440
+ //
441
+ // nameserver can be a IPv4 or IPv6 address
442
+ //
443
+ if ( (self::isIPv4($value) == true)
444
+ || (self::isIPv6($value) == true)
445
+ ) {
446
+
447
+ $ns[] = $value;
448
+ } else {
449
+
450
+ throw new Net_DNS2_Exception(
451
+ 'invalid nameserver entry: ' . $value,
452
+ Net_DNS2_Lookups::E_NS_INVALID_ENTRY
453
+ );
454
+ }
455
+ break;
456
+
457
+ case 'domain':
458
+ $this->domain = $value;
459
+ break;
460
+
461
+ case 'search':
462
+ $this->search_list = preg_split('/\s+/', $value);
463
+ break;
464
+
465
+ case 'options':
466
+ $this->parseOptions($value);
467
+ break;
468
+
469
+ default:
470
+ ;
471
+ }
472
+ }
473
+
474
+ //
475
+ // if we don't have a domain, but we have a search list, then
476
+ // take the first entry on the search list as the domain
477
+ //
478
+ if ( (strlen($this->domain) == 0)
479
+ && (count($this->search_list) > 0)
480
+ ) {
481
+ $this->domain = $this->search_list[0];
482
+ }
483
+
484
+ } else {
485
+ throw new Net_DNS2_Exception(
486
+ 'resolver file file provided is not readable: ' . $nameservers,
487
+ Net_DNS2_Lookups::E_NS_INVALID_FILE
488
+ );
489
+ }
490
+
491
+ //
492
+ // store the name servers locally
493
+ //
494
+ if (count($ns) > 0) {
495
+ $this->nameservers = $ns;
496
+ }
497
+ }
498
+
499
+ //
500
+ // remove any duplicates; not sure if we should bother with this- if people
501
+ // put duplicate name servers, who I am to stop them?
502
+ //
503
+ $this->nameservers = array_unique($this->nameservers);
504
+
505
+ //
506
+ // check the name servers
507
+ //
508
+ $this->checkServers();
509
+
510
+ return true;
511
+ }
512
+
513
+ /**
514
+ * parses the options line from a resolv.conf file; we don't support all the options
515
+ * yet, and using them is optional.
516
+ *
517
+ * @param string $value is the options string from the resolv.conf file.
518
+ *
519
+ * @return boolean
520
+ * @access private
521
+ *
522
+ */
523
+ private function parseOptions($value)
524
+ {
525
+ //
526
+ // if overrides are disabled (the default), or the options list is empty for some
527
+ // reason, then we don't need to do any of this work.
528
+ //
529
+ if ( ($this->use_resolv_options == false) || (strlen($value) == 0) ) {
530
+
531
+ return true;
532
+ }
533
+
534
+ $options = preg_split('/\s+/', strtolower($value));
535
+
536
+ foreach ($options as $option) {
537
+
538
+ //
539
+ // override the timeout value from the resolv.conf file.
540
+ //
541
+ if ( (strncmp($option, 'timeout', 7) == 0) && (strpos($option, ':') !== false) ) {
542
+
543
+ list($key, $val) = explode(':', $option);
544
+
545
+ if ( ($val > 0) && ($val <= 30) ) {
546
+
547
+ $this->timeout = $val;
548
+ }
549
+
550
+ //
551
+ // the rotate option just enabled the ns_random option
552
+ //
553
+ } else if (strncmp($option, 'rotate', 6) == 0) {
554
+
555
+ $this->ns_random = true;
556
+ }
557
+ }
558
+
559
+ return true;
560
+ }
561
+
562
+ /**
563
+ * checks the list of name servers to make sure they're set
564
+ *
565
+ * @param mixed $default a path to a resolv.conf file or an array of servers.
566
+ *
567
+ * @return boolean
568
+ * @throws Net_DNS2_Exception
569
+ * @access protected
570
+ *
571
+ */
572
+ protected function checkServers($default = null)
573
+ {
574
+ if (empty($this->nameservers)) {
575
+
576
+ if (isset($default)) {
577
+
578
+ $this->setServers($default);
579
+ } else {
580
+
581
+ throw new Net_DNS2_Exception(
582
+ 'empty name servers list; you must provide a list of name '.
583
+ 'servers, or the path to a resolv.conf file.',
584
+ Net_DNS2_Lookups::E_NS_INVALID_ENTRY
585
+ );
586
+ }
587
+ }
588
+
589
+ return true;
590
+ }
591
+
592
+ /**
593
+ * adds a TSIG RR object for authentication
594
+ *
595
+ * @param string $keyname the key name to use for the TSIG RR
596
+ * @param string $signature the key to sign the request.
597
+ * @param string $algorithm the algorithm to use
598
+ *
599
+ * @return boolean
600
+ * @access public
601
+ * @since function available since release 1.1.0
602
+ *
603
+ */
604
+ public function signTSIG(
605
+ $keyname, $signature = '', $algorithm = Net_DNS2_RR_TSIG::HMAC_MD5
606
+ ) {
607
+ //
608
+ // if the TSIG was pre-created and passed in, then we can just used
609
+ // it as provided.
610
+ //
611
+ if ($keyname instanceof Net_DNS2_RR_TSIG) {
612
+
613
+ $this->auth_signature = $keyname;
614
+
615
+ } else {
616
+
617
+ //
618
+ // otherwise create the TSIG RR, but don't add it just yet; TSIG needs
619
+ // to be added as the last additional entry- so we'll add it just
620
+ // before we send.
621
+ //
622
+ $this->auth_signature = Net_DNS2_RR::fromString(
623
+ strtolower(trim($keyname)) .
624
+ ' TSIG '. $signature
625
+ );
626
+
627
+ //
628
+ // set the algorithm to use
629
+ //
630
+ $this->auth_signature->algorithm = $algorithm;
631
+ }
632
+
633
+ return true;
634
+ }
635
+
636
+ /**
637
+ * adds a SIG RR object for authentication
638
+ *
639
+ * @param string $filename the name of a file to load the signature from.
640
+ *
641
+ * @return boolean
642
+ * @throws Net_DNS2_Exception
643
+ * @access public
644
+ * @since function available since release 1.1.0
645
+ *
646
+ */
647
+ public function signSIG0($filename)
648
+ {
649
+ //
650
+ // check for OpenSSL
651
+ //
652
+ if (extension_loaded('openssl') === false) {
653
+
654
+ throw new Net_DNS2_Exception(
655
+ 'the OpenSSL extension is required to use SIG(0).',
656
+ Net_DNS2_Lookups::E_OPENSSL_UNAVAIL
657
+ );
658
+ }
659
+
660
+ //
661
+ // if the SIG was pre-created, then use it as-is
662
+ //
663
+ if ($filename instanceof Net_DNS2_RR_SIG) {
664
+
665
+ $this->auth_signature = $filename;
666
+
667
+ } else {
668
+
669
+ //
670
+ // otherwise, it's filename which needs to be parsed and processed.
671
+ //
672
+ $private = new Net_DNS2_PrivateKey($filename);
673
+
674
+ //
675
+ // create a new Net_DNS2_RR_SIG object
676
+ //
677
+ $this->auth_signature = new Net_DNS2_RR_SIG();
678
+
679
+ //
680
+ // reset some values
681
+ //
682
+ $this->auth_signature->name = $private->signname;
683
+ $this->auth_signature->ttl = 0;
684
+ $this->auth_signature->class = 'ANY';
685
+
686
+ //
687
+ // these values are pulled from the private key
688
+ //
689
+ $this->auth_signature->algorithm = $private->algorithm;
690
+ $this->auth_signature->keytag = $private->keytag;
691
+ $this->auth_signature->signname = $private->signname;
692
+
693
+ //
694
+ // these values are hard-coded for SIG0
695
+ //
696
+ $this->auth_signature->typecovered = 'SIG0';
697
+ $this->auth_signature->labels = 0;
698
+ $this->auth_signature->origttl = 0;
699
+
700
+ //
701
+ // generate the dates
702
+ //
703
+ $t = time();
704
+
705
+ $this->auth_signature->sigincep = gmdate('YmdHis', $t);
706
+ $this->auth_signature->sigexp = gmdate('YmdHis', $t + 500);
707
+
708
+ //
709
+ // store the private key in the SIG object for later.
710
+ //
711
+ $this->auth_signature->private_key = $private;
712
+ }
713
+
714
+ //
715
+ // only RSA algorithms are supported for SIG(0)
716
+ //
717
+ switch($this->auth_signature->algorithm) {
718
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSAMD5:
719
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA1:
720
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA256:
721
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA512:
722
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_DSA:
723
+ break;
724
+ default:
725
+ throw new Net_DNS2_Exception(
726
+ 'only asymmetric algorithms work with SIG(0)!',
727
+ Net_DNS2_Lookups::E_OPENSSL_INV_ALGO
728
+ );
729
+ }
730
+
731
+ return true;
732
+ }
733
+
734
+ /**
735
+ * a simple function to determine if the RR type is cacheable
736
+ *
737
+ * @param stream $_type the RR type string
738
+ *
739
+ * @return bool returns true/false if the RR type if cachable
740
+ * @access public
741
+ *
742
+ */
743
+ public function cacheable($_type)
744
+ {
745
+ switch($_type) {
746
+ case 'AXFR':
747
+ case 'OPT':
748
+ return false;
749
+ }
750
+
751
+ return true;
752
+ }
753
+
754
+ /**
755
+ * PHP doesn't support unsigned integers, but many of the RR's return
756
+ * unsigned values (like SOA), so there is the possibility that the
757
+ * value will overrun on 32bit systems, and you'll end up with a
758
+ * negative value.
759
+ *
760
+ * 64bit systems are not affected, as their PHP_IN_MAX value should
761
+ * be 64bit (ie 9223372036854775807)
762
+ *
763
+ * This function returns a negative integer value, as a string, with
764
+ * the correct unsigned value.
765
+ *
766
+ * @param string $_int the unsigned integer value to check
767
+ *
768
+ * @return string returns the unsigned value as a string.
769
+ * @access public
770
+ *
771
+ */
772
+ public static function expandUint32($_int)
773
+ {
774
+ if ( ($_int < 0) && (PHP_INT_MAX == 2147483647) ) {
775
+ return sprintf('%u', $_int);
776
+ } else {
777
+ return $_int;
778
+ }
779
+ }
780
+
781
+ /**
782
+ * returns true/false if the given address is a valid IPv4 address
783
+ *
784
+ * @param string $_address the IPv4 address to check
785
+ *
786
+ * @return boolean returns true/false if the address is IPv4 address
787
+ * @access public
788
+ *
789
+ */
790
+ public static function isIPv4($_address)
791
+ {
792
+ //
793
+ // use filter_var() if it's available; it's faster than preg
794
+ //
795
+ if (extension_loaded('filter') == true) {
796
+
797
+ if (filter_var($_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) == false) {
798
+ return false;
799
+ }
800
+ } else {
801
+
802
+ //
803
+ // do the main check here;
804
+ //
805
+ if (inet_pton($_address) === false) {
806
+ return false;
807
+ }
808
+
809
+ //
810
+ // then make sure we're not a IPv6 address
811
+ //
812
+ if (preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/', $_address) == 0) {
813
+ return false;
814
+ }
815
+ }
816
+
817
+ return true;
818
+ }
819
+
820
+ /**
821
+ * returns true/false if the given address is a valid IPv6 address
822
+ *
823
+ * @param string $_address the IPv6 address to check
824
+ *
825
+ * @return boolean returns true/false if the address is IPv6 address
826
+ * @access public
827
+ *
828
+ */
829
+ public static function isIPv6($_address)
830
+ {
831
+ //
832
+ // use filter_var() if it's available; it's faster than preg
833
+ //
834
+ if (extension_loaded('filter') == true) {
835
+ if (filter_var($_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) == false) {
836
+ return false;
837
+ }
838
+ } else {
839
+
840
+ //
841
+ // do the main check here
842
+ //
843
+ if (inet_pton($_address) === false) {
844
+ return false;
845
+ }
846
+
847
+ //
848
+ // then make sure it doesn't match a IPv4 address
849
+ //
850
+ if (preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/', $_address) == 1) {
851
+ return false;
852
+ }
853
+ }
854
+
855
+ return true;
856
+ }
857
+
858
+ /**
859
+ * formats the given IPv6 address as a fully expanded IPv6 address
860
+ *
861
+ * @param string $_address the IPv6 address to expand
862
+ *
863
+ * @return string the fully expanded IPv6 address
864
+ * @access public
865
+ *
866
+ */
867
+ public static function expandIPv6($_address)
868
+ {
869
+ if (strpos($_address, '::') !== false) {
870
+
871
+ $part = explode('::', $_address);
872
+ $part[0] = explode(':', $part[0]);
873
+ $part[1] = explode(':', $part[1]);
874
+
875
+ $missing = array();
876
+
877
+ $x = (8 - (count($part[0]) + count($part[1])));
878
+ for ($i = 0; $i < $x; $i++) {
879
+
880
+ array_push($missing, '0000');
881
+ }
882
+
883
+ $missing = array_merge($part[0], $missing);
884
+ $part = array_merge($missing, $part[1]);
885
+
886
+ } else {
887
+
888
+ $part = explode(':', $_address);
889
+ }
890
+
891
+ foreach ($part as &$p) {
892
+ while (strlen($p) < 4) {
893
+ $p = '0' . $p;
894
+ }
895
+ }
896
+
897
+ unset($p);
898
+
899
+ $result = implode(':', $part);
900
+
901
+ if (strlen($result) == 39) {
902
+ return $result;
903
+ } else {
904
+ return false;
905
+ }
906
+ }
907
+
908
+ /**
909
+ * sends a standard Net_DNS2_Packet_Request packet
910
+ *
911
+ * @param Net_DNS2_Packet $request a Net_DNS2_Packet_Request object
912
+ * @param boolean $use_tcp true/false if the function should
913
+ * use TCP for the request
914
+ *
915
+ * @return mixed returns a Net_DNS2_Packet_Response object, or false on error
916
+ * @throws Net_DNS2_Exception
917
+ * @access protected
918
+ *
919
+ */
920
+ protected function sendPacket(Net_DNS2_Packet $request, $use_tcp)
921
+ {
922
+ //
923
+ // get the data from the packet
924
+ //
925
+ $data = $request->get();
926
+ if (strlen($data) < Net_DNS2_Lookups::DNS_HEADER_SIZE) {
927
+
928
+ throw new Net_DNS2_Exception(
929
+ 'invalid or empty packet for sending!',
930
+ Net_DNS2_Lookups::E_PACKET_INVALID,
931
+ null,
932
+ $request
933
+ );
934
+ }
935
+
936
+ reset($this->nameservers);
937
+
938
+ //
939
+ // randomize the name server list if it's asked for
940
+ //
941
+ if ($this->ns_random == true) {
942
+
943
+ shuffle($this->nameservers);
944
+ }
945
+
946
+ //
947
+ // loop so we can handle server errors
948
+ //
949
+ $response = null;
950
+ $ns = '';
951
+
952
+ while (1) {
953
+
954
+ //
955
+ // grab the next DNS server
956
+ //
957
+ $ns = each($this->nameservers);
958
+ if ($ns === false) {
959
+
960
+ if (is_null($this->last_exception) == false) {
961
+
962
+ throw $this->last_exception;
963
+ } else {
964
+
965
+ throw new Net_DNS2_Exception(
966
+ 'every name server provided has failed',
967
+ Net_DNS2_Lookups::E_NS_FAILED
968
+ );
969
+ }
970
+ }
971
+
972
+ $ns = $ns[1];
973
+
974
+ //
975
+ // if the use TCP flag (force TCP) is set, or the packet is bigger than our
976
+ // max allowed UDP size- which is either 512, or if this is DNSSEC request,
977
+ // then whatever the configured dnssec_payload_size is.
978
+ //
979
+ $max_udp_size = Net_DNS2_Lookups::DNS_MAX_UDP_SIZE;
980
+ if ($this->dnssec == true)
981
+ {
982
+ $max_udp_size = $this->dnssec_payload_size;
983
+ }
984
+
985
+ if ( ($use_tcp == true) || (strlen($data) > $max_udp_size) ) {
986
+
987
+ try
988
+ {
989
+ $response = $this->sendTCPRequest($ns, $data, ($request->question[0]->qtype == 'AXFR') ? true : false);
990
+
991
+ } catch(Net_DNS2_Exception $e) {
992
+
993
+ $this->last_exception = $e;
994
+ $this->last_exception_list[$ns] = $e;
995
+
996
+ continue;
997
+ }
998
+
999
+ //
1000
+ // otherwise, send it using UDP
1001
+ //
1002
+ } else {
1003
+
1004
+ try
1005
+ {
1006
+ $response = $this->sendUDPRequest($ns, $data);
1007
+
1008
+ //
1009
+ // check the packet header for a trucated bit; if it was truncated,
1010
+ // then re-send the request as TCP.
1011
+ //
1012
+ if ($response->header->tc == 1) {
1013
+
1014
+ $response = $this->sendTCPRequest($ns, $data);
1015
+ }
1016
+
1017
+ } catch(Net_DNS2_Exception $e) {
1018
+
1019
+ $this->last_exception = $e;
1020
+ $this->last_exception_list[$ns] = $e;
1021
+
1022
+ continue;
1023
+ }
1024
+ }
1025
+
1026
+ //
1027
+ // make sure header id's match between the request and response
1028
+ //
1029
+ if ($request->header->id != $response->header->id) {
1030
+
1031
+ $this->last_exception = new Net_DNS2_Exception(
1032
+
1033
+ 'invalid header: the request and response id do not match.',
1034
+ Net_DNS2_Lookups::E_HEADER_INVALID,
1035
+ null,
1036
+ $request,
1037
+ $response
1038
+ );
1039
+
1040
+ $this->last_exception_list[$ns] = $this->last_exception;
1041
+ continue;
1042
+ }
1043
+
1044
+ //
1045
+ // make sure the response is actually a response
1046
+ //
1047
+ // 0 = query, 1 = response
1048
+ //
1049
+ if ($response->header->qr != Net_DNS2_Lookups::QR_RESPONSE) {
1050
+
1051
+ $this->last_exception = new Net_DNS2_Exception(
1052
+
1053
+ 'invalid header: the response provided is not a response packet.',
1054
+ Net_DNS2_Lookups::E_HEADER_INVALID,
1055
+ null,
1056
+ $request,
1057
+ $response
1058
+ );
1059
+
1060
+ $this->last_exception_list[$ns] = $this->last_exception;
1061
+ continue;
1062
+ }
1063
+
1064
+ //
1065
+ // make sure the response code in the header is ok
1066
+ //
1067
+ if ($response->header->rcode != Net_DNS2_Lookups::RCODE_NOERROR) {
1068
+
1069
+ $this->last_exception = new Net_DNS2_Exception(
1070
+
1071
+ 'DNS request failed: ' .
1072
+ Net_DNS2_Lookups::$result_code_messages[$response->header->rcode],
1073
+ $response->header->rcode,
1074
+ null,
1075
+ $request,
1076
+ $response
1077
+ );
1078
+
1079
+ $this->last_exception_list[$ns] = $this->last_exception;
1080
+ continue;
1081
+ }
1082
+
1083
+ break;
1084
+ }
1085
+
1086
+ return $response;
1087
+ }
1088
+
1089
+ /**
1090
+ * sends a DNS request using TCP
1091
+ *
1092
+ * @param string $_ns the name server to use for the request
1093
+ * @param string $_data the raw DNS packet data
1094
+ * @param boolean $_axfr if this is a zone transfer request
1095
+ *
1096
+ * @return Net_DNS2_Packet_Response the reponse object
1097
+ * @throws Net_DNS2_Exception
1098
+ * @access private
1099
+ *
1100
+ */
1101
+ private function sendTCPRequest($_ns, $_data, $_axfr = false)
1102
+ {
1103
+ //
1104
+ // grab the start time
1105
+ //
1106
+ $start_time = microtime(true);
1107
+
1108
+ //
1109
+ // see if we already have an open socket from a previous request; if so, try to use
1110
+ // that instead of opening a new one.
1111
+ //
1112
+ if ( (!isset($this->sock['tcp'][$_ns]))
1113
+ || (!($this->sock['tcp'][$_ns] instanceof Net_DNS2_Socket))
1114
+ ) {
1115
+
1116
+ //
1117
+ // if the socket library is available, then use that
1118
+ //
1119
+ if ($this->sockets_enabled === true) {
1120
+
1121
+ $this->sock['tcp'][$_ns] = new Net_DNS2_Socket_Sockets(
1122
+ Net_DNS2_Socket::SOCK_STREAM, $_ns, $this->dns_port, $this->timeout
1123
+ );
1124
+
1125
+ //
1126
+ // otherwise the streams library
1127
+ //
1128
+ } else {
1129
+
1130
+ $this->sock['tcp'][$_ns] = new Net_DNS2_Socket_Streams(
1131
+ Net_DNS2_Socket::SOCK_STREAM, $_ns, $this->dns_port, $this->timeout
1132
+ );
1133
+ }
1134
+
1135
+ //
1136
+ // if a local IP address / port is set, then add it
1137
+ //
1138
+ if (strlen($this->local_host) > 0) {
1139
+
1140
+ $this->sock['tcp'][$_ns]->bindAddress(
1141
+ $this->local_host, $this->local_port
1142
+ );
1143
+ }
1144
+
1145
+ //
1146
+ // open the socket
1147
+ //
1148
+ if ($this->sock['tcp'][$_ns]->open() === false) {
1149
+
1150
+ throw new Net_DNS2_Exception(
1151
+ $this->sock['tcp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1152
+ );
1153
+ }
1154
+ }
1155
+
1156
+ //
1157
+ // write the data to the socket; if it fails, continue on
1158
+ // the while loop
1159
+ //
1160
+ if ($this->sock['tcp'][$_ns]->write($_data) === false) {
1161
+
1162
+ throw new Net_DNS2_Exception(
1163
+ $this->sock['tcp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1164
+ );
1165
+ }
1166
+
1167
+ //
1168
+ // read the content, using select to wait for a response
1169
+ //
1170
+ $size = 0;
1171
+ $result = null;
1172
+ $response = null;
1173
+
1174
+ //
1175
+ // handle zone transfer requests differently than other requests.
1176
+ //
1177
+ if ($_axfr == true) {
1178
+
1179
+ $soa_count = 0;
1180
+
1181
+ while (1) {
1182
+
1183
+ //
1184
+ // read the data off the socket
1185
+ //
1186
+ $result = $this->sock['tcp'][$_ns]->read($size, ($this->dnssec == true) ? $this->dnssec_payload_size : Net_DNS2_Lookups::DNS_MAX_UDP_SIZE);
1187
+ if ( ($result === false) || ($size < Net_DNS2_Lookups::DNS_HEADER_SIZE) ) {
1188
+
1189
+ throw new Net_DNS2_Exception(
1190
+ $this->sock['tcp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1191
+ );
1192
+ }
1193
+
1194
+ //
1195
+ // parse the first chunk as a packet
1196
+ //
1197
+ $chunk = new Net_DNS2_Packet_Response($result, $size);
1198
+
1199
+ //
1200
+ // if this is the first packet, then clone it directly, then
1201
+ // go through it to see if there are two SOA records
1202
+ // (indicating that it's the only packet)
1203
+ //
1204
+ if (is_null($response) == true) {
1205
+
1206
+ $response = clone $chunk;
1207
+
1208
+ //
1209
+ // look for a failed response; if the zone transfer
1210
+ // failed, then we don't need to do anything else at this
1211
+ // point, and we should just break out.
1212
+ //
1213
+ if ($response->header->rcode != Net_DNS2_Lookups::RCODE_NOERROR) {
1214
+ break;
1215
+ }
1216
+
1217
+ //
1218
+ // go through each answer
1219
+ //
1220
+ foreach ($response->answer as $index => $rr) {
1221
+
1222
+ //
1223
+ // count the SOA records
1224
+ //
1225
+ if ($rr->type == 'SOA') {
1226
+ $soa_count++;
1227
+ }
1228
+ }
1229
+
1230
+ //
1231
+ // if we have 2 or more SOA records, then we're done;
1232
+ // otherwise continue out so we read the rest of the
1233
+ // packets off the socket
1234
+ //
1235
+ if ($soa_count >= 2) {
1236
+ break;
1237
+ } else {
1238
+ continue;
1239
+ }
1240
+
1241
+ } else {
1242
+
1243
+ //
1244
+ // go through all these answers, and look for SOA records
1245
+ //
1246
+ foreach ($chunk->answer as $index => $rr) {
1247
+
1248
+ //
1249
+ // count the number of SOA records we find
1250
+ //
1251
+ if ($rr->type == 'SOA') {
1252
+ $soa_count++;
1253
+ }
1254
+
1255
+ //
1256
+ // add the records to a single response object
1257
+ //
1258
+ $response->answer[] = $rr;
1259
+ }
1260
+
1261
+ //
1262
+ // if we've found the second SOA record, we're done
1263
+ //
1264
+ if ($soa_count >= 2) {
1265
+ break;
1266
+ }
1267
+ }
1268
+ }
1269
+
1270
+ //
1271
+ // everything other than a AXFR
1272
+ //
1273
+ } else {
1274
+
1275
+ $result = $this->sock['tcp'][$_ns]->read($size, ($this->dnssec == true) ? $this->dnssec_payload_size : Net_DNS2_Lookups::DNS_MAX_UDP_SIZE);
1276
+ if ( ($result === false) || ($size < Net_DNS2_Lookups::DNS_HEADER_SIZE) ) {
1277
+
1278
+ throw new Net_DNS2_Exception(
1279
+ $this->sock['tcp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1280
+ );
1281
+ }
1282
+
1283
+ //
1284
+ // create the packet object
1285
+ //
1286
+ $response = new Net_DNS2_Packet_Response($result, $size);
1287
+ }
1288
+
1289
+ //
1290
+ // store the query time
1291
+ //
1292
+ $response->response_time = microtime(true) - $start_time;
1293
+
1294
+ //
1295
+ // add the name server that the response came from to the response object,
1296
+ // and the socket type that was used.
1297
+ //
1298
+ $response->answer_from = $_ns;
1299
+ $response->answer_socket_type = Net_DNS2_Socket::SOCK_STREAM;
1300
+
1301
+ //
1302
+ // return the Net_DNS2_Packet_Response object
1303
+ //
1304
+ return $response;
1305
+ }
1306
+
1307
+ /**
1308
+ * sends a DNS request using UDP
1309
+ *
1310
+ * @param string $_ns the name server to use for the request
1311
+ * @param string $_data the raw DNS packet data
1312
+ *
1313
+ * @return Net_DNS2_Packet_Response the reponse object
1314
+ * @throws Net_DNS2_Exception
1315
+ * @access private
1316
+ *
1317
+ */
1318
+ private function sendUDPRequest($_ns, $_data)
1319
+ {
1320
+ //
1321
+ // grab the start time
1322
+ //
1323
+ $start_time = microtime(true);
1324
+
1325
+ //
1326
+ // see if we already have an open socket from a previous request; if so, try to use
1327
+ // that instead of opening a new one.
1328
+ //
1329
+ if ( (!isset($this->sock['udp'][$_ns]))
1330
+ || (!($this->sock['udp'][$_ns] instanceof Net_DNS2_Socket))
1331
+ ) {
1332
+
1333
+ //
1334
+ // if the socket library is available, then use that
1335
+ //
1336
+ if ($this->sockets_enabled === true) {
1337
+
1338
+ $this->sock['udp'][$_ns] = new Net_DNS2_Socket_Sockets(
1339
+ Net_DNS2_Socket::SOCK_DGRAM, $_ns, $this->dns_port, $this->timeout
1340
+ );
1341
+
1342
+ //
1343
+ // otherwise the streams library
1344
+ //
1345
+ } else {
1346
+
1347
+ $this->sock['udp'][$_ns] = new Net_DNS2_Socket_Streams(
1348
+ Net_DNS2_Socket::SOCK_DGRAM, $_ns, $this->dns_port, $this->timeout
1349
+ );
1350
+ }
1351
+
1352
+ //
1353
+ // if a local IP address / port is set, then add it
1354
+ //
1355
+ if (strlen($this->local_host) > 0) {
1356
+
1357
+ $this->sock['udp'][$_ns]->bindAddress(
1358
+ $this->local_host, $this->local_port
1359
+ );
1360
+ }
1361
+
1362
+ //
1363
+ // open the socket
1364
+ //
1365
+ if ($this->sock['udp'][$_ns]->open() === false) {
1366
+
1367
+ throw new Net_DNS2_Exception(
1368
+ $this->sock['udp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1369
+ );
1370
+ }
1371
+ }
1372
+
1373
+ //
1374
+ // write the data to the socket
1375
+ //
1376
+ if ($this->sock['udp'][$_ns]->write($_data) === false) {
1377
+
1378
+ throw new Net_DNS2_Exception(
1379
+ $this->sock['udp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1380
+ );
1381
+ }
1382
+
1383
+ //
1384
+ // read the content, using select to wait for a response
1385
+ //
1386
+ $size = 0;
1387
+
1388
+ $result = $this->sock['udp'][$_ns]->read($size, ($this->dnssec == true) ? $this->dnssec_payload_size : Net_DNS2_Lookups::DNS_MAX_UDP_SIZE);
1389
+ if (( $result === false) || ($size < Net_DNS2_Lookups::DNS_HEADER_SIZE)) {
1390
+
1391
+ throw new Net_DNS2_Exception(
1392
+ $this->sock['udp'][$_ns]->last_error, Net_DNS2_Lookups::E_NS_SOCKET_FAILED
1393
+ );
1394
+ }
1395
+
1396
+ //
1397
+ // create the packet object
1398
+ //
1399
+ $response = new Net_DNS2_Packet_Response($result, $size);
1400
+
1401
+ //
1402
+ // store the query time
1403
+ //
1404
+ $response->response_time = microtime(true) - $start_time;
1405
+
1406
+ //
1407
+ // add the name server that the response came from to the response object,
1408
+ // and the socket type that was used.
1409
+ //
1410
+ $response->answer_from = $_ns;
1411
+ $response->answer_socket_type = Net_DNS2_Socket::SOCK_DGRAM;
1412
+
1413
+ //
1414
+ // return the Net_DNS2_Packet_Response object
1415
+ //
1416
+ return $response;
1417
+ }
1418
+ }
1419
+
1420
+ /*
1421
+ * Local variables:
1422
+ * tab-width: 4
1423
+ * c-basic-offset: 4
1424
+ * c-hanging-comment-ender-p: nil
1425
+ * End:
1426
+ */
1427
+ ?>
includes/Net/DNS2/BitMap.php ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * a class to handle converting RR bitmaps to arrays and back; used on NSEC
54
+ * and NSEC3 RR's
55
+ *
56
+ * @category Networking
57
+ * @package Net_DNS2
58
+ * @author Mike Pultz <mike@mikepultz.com>
59
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
60
+ * @link http://pear.php.net/package/Net_DNS2
61
+ * @see Net_DNS2_Packet
62
+ *
63
+ */
64
+ class Net_DNS2_BitMap
65
+ {
66
+ /**
67
+ * parses a RR bitmap field defined in RFC3845, into an array of RR names.
68
+ *
69
+ * Type Bit Map(s) Field = ( Window Block # | Bitmap Length | Bitmap ) +
70
+ *
71
+ * @param string $data a bitmap stringto parse
72
+ *
73
+ * @return array
74
+ * @access public
75
+ *
76
+ */
77
+ public static function bitMapToArray($data)
78
+ {
79
+ if (strlen($data) == 0) {
80
+ return null;
81
+ }
82
+
83
+ $output = array();
84
+ $offset = 0;
85
+ $length = strlen($data);
86
+
87
+ while ($offset < $length) {
88
+
89
+ //
90
+ // unpack the window and length values
91
+ //
92
+ $x = unpack('@' . $offset . '/Cwindow/Clength', $data);
93
+ $offset += 2;
94
+
95
+ //
96
+ // copy out the bitmap value
97
+ //
98
+ $bitmap = unpack('C*', substr($data, $offset, $x['length']));
99
+ $offset += $x['length'];
100
+
101
+ //
102
+ // I'm not sure if there's a better way of doing this, but PHP doesn't
103
+ // have a 'B' flag for unpack()
104
+ //
105
+ $bitstr = '';
106
+ foreach ($bitmap as $r) {
107
+
108
+ $bitstr .= sprintf('%08b', $r);
109
+ }
110
+
111
+ $blen = strlen($bitstr);
112
+ for ($i=0; $i<$blen; $i++) {
113
+
114
+ if ($bitstr[$i] == '1') {
115
+
116
+ $type = $x['window'] * 256 + $i;
117
+
118
+ if (isset(Net_DNS2_Lookups::$rr_types_by_id[$type])) {
119
+
120
+ $output[] = Net_DNS2_Lookups::$rr_types_by_id[$type];
121
+ } else {
122
+
123
+ $output[] = 'TYPE' . $type;
124
+ }
125
+ }
126
+ }
127
+ }
128
+
129
+ return $output;
130
+ }
131
+
132
+ /**
133
+ * builds a RR Bit map from an array of RR type names
134
+ *
135
+ * @param array $data a list of RR names
136
+ *
137
+ * @return string
138
+ * @access public
139
+ *
140
+ */
141
+ public static function arrayToBitMap(array $data)
142
+ {
143
+ if (count($data) == 0) {
144
+ return null;
145
+ }
146
+
147
+ $current_window = 0;
148
+
149
+ //
150
+ // go through each RR
151
+ //
152
+ $max = 0;
153
+ $bm = array();
154
+
155
+ foreach ($data as $rr) {
156
+
157
+ $rr = strtoupper($rr);
158
+
159
+ //
160
+ // get the type id for the RR
161
+ //
162
+ $type = @Net_DNS2_Lookups::$rr_types_by_name[$rr];
163
+ if (isset($type)) {
164
+
165
+ //
166
+ // skip meta types or qtypes
167
+ //
168
+ if ( (isset(Net_DNS2_Lookups::$rr_qtypes_by_id[$type]))
169
+ || (isset(Net_DNS2_Lookups::$rr_metatypes_by_id[$type]))
170
+ ) {
171
+ continue;
172
+ }
173
+
174
+ } else {
175
+
176
+ //
177
+ // if it's not found, then it must be defined as TYPE<id>, per
178
+ // RFC3845 section 2.2, if it's not, we ignore it.
179
+ //
180
+ list($name, $type) = explode('TYPE', $rr);
181
+ if (!isset($type)) {
182
+
183
+ continue;
184
+ }
185
+ }
186
+
187
+ //
188
+ // build the current window
189
+ //
190
+ $current_window = (int)($type / 256);
191
+
192
+ $val = $type - $current_window * 256.0;
193
+ if ($val > $max) {
194
+ $max = $val;
195
+ }
196
+
197
+ $bm[$current_window][$val] = 1;
198
+ $bm[$current_window]['length'] = ceil(($max + 1) / 8);
199
+ }
200
+
201
+ $output = '';
202
+
203
+ foreach ($bm as $window => $bitdata) {
204
+
205
+ $bitstr = '';
206
+
207
+ for ($i=0; $i<$bm[$window]['length'] * 8; $i++) {
208
+ if (isset($bm[$window][$i])) {
209
+ $bitstr .= '1';
210
+ } else {
211
+ $bitstr .= '0';
212
+ }
213
+ }
214
+
215
+ $output .= pack('CC', $window, $bm[$window]['length']);
216
+ $output .= pack('H*', self::bigBaseConvert($bitstr));
217
+ }
218
+
219
+ return $output;
220
+ }
221
+
222
+ /**
223
+ * a base_convert that handles large numbers; forced to 2/16
224
+ *
225
+ * @param string $number a bit string
226
+ *
227
+ * @return string
228
+ * @access public
229
+ *
230
+ */
231
+ public static function bigBaseConvert($number)
232
+ {
233
+ $result = '';
234
+
235
+ $bin = substr(chunk_split(strrev($number), 4, '-'), 0, -1);
236
+ $temp = preg_split('[-]', $bin, -1, PREG_SPLIT_DELIM_CAPTURE);
237
+
238
+ for ($i = count($temp)-1;$i >= 0;$i--) {
239
+
240
+ $result = $result . base_convert(strrev($temp[$i]), 2, 16);
241
+ }
242
+
243
+ return strtoupper($result);
244
+ }
245
+ }
246
+
247
+ /*
248
+ * Local variables:
249
+ * tab-width: 4
250
+ * c-basic-offset: 4
251
+ * c-hanging-comment-ender-p: nil
252
+ * End:
253
+ */
254
+ ?>
includes/Net/DNS2/Cache.php ADDED
@@ -0,0 +1,305 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.1.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * A class to provide simple dns lookup caching.
54
+ *
55
+ * @category Networking
56
+ * @package Net_DNS2
57
+ * @author Mike Pultz <mike@mikepultz.com>
58
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
59
+ * @link http://pear.php.net/package/Net_DNS2
60
+ * @see Net_DNS2_Packet
61
+ *
62
+ */
63
+ class Net_DNS2_Cache
64
+ {
65
+ /*
66
+ * the filename of the cache file
67
+ */
68
+ protected $cache_file = '';
69
+
70
+ /*
71
+ * the local data store for the cache
72
+ */
73
+ protected $cache_data = array();
74
+
75
+ /*
76
+ * the size of the cache to use
77
+ */
78
+ protected $cache_size = 0;
79
+
80
+ /*
81
+ * the cache serializer
82
+ */
83
+ protected $cache_serializer;
84
+
85
+ /**
86
+ * returns true/false if the provided key is defined in the cache
87
+ *
88
+ * @param string $key the key to lookup in the local cache
89
+ *
90
+ * @return boolean
91
+ * @access public
92
+ *
93
+ */
94
+ public function has($key)
95
+ {
96
+ return isset($this->cache_data[$key]);
97
+ }
98
+
99
+ /**
100
+ * returns the value for the given key
101
+ *
102
+ * @param string $key the key to lookup in the local cache
103
+ *
104
+ * @return mixed returns the cache data on sucess, false on error
105
+ * @access public
106
+ *
107
+ */
108
+ public function get($key)
109
+ {
110
+ if (isset($this->cache_data[$key])) {
111
+
112
+ if ($this->cache_serializer == 'json') {
113
+ return json_decode($this->cache_data[$key]['object']);
114
+ } else {
115
+ return unserialize($this->cache_data[$key]['object']);
116
+ }
117
+ } else {
118
+
119
+ return false;
120
+ }
121
+ }
122
+
123
+ /**
124
+ * adds a new key/value pair to the cache
125
+ *
126
+ * @param string $key the key for the new cache entry
127
+ * @param mixed $data the data to store in cache
128
+ *
129
+ * @return void
130
+ * @access public
131
+ *
132
+ */
133
+ public function put($key, $data)
134
+ {
135
+ $ttl = 86400 * 365;
136
+
137
+ //
138
+ // clear the rdata values
139
+ //
140
+ $data->rdata = '';
141
+ $data->rdlength = 0;
142
+
143
+ //
144
+ // find the lowest TTL, and use that as the TTL for the whole cached
145
+ // object. The downside to using one TTL for the whole object, is that
146
+ // we'll invalidate entries before they actuall expire, causing a
147
+ // real lookup to happen.
148
+ //
149
+ // The upside is that we don't need to require() each RR type in the
150
+ // cache, so we can look at their individual TTL's on each run- we only
151
+ // unserialize the actual RR object when it's get() from the cache.
152
+ //
153
+ foreach ($data->answer as $index => $rr) {
154
+
155
+ if ($rr->ttl < $ttl) {
156
+ $ttl = $rr->ttl;
157
+ }
158
+
159
+ $rr->rdata = '';
160
+ $rr->rdlength = 0;
161
+ }
162
+ foreach ($data->authority as $index => $rr) {
163
+
164
+ if ($rr->ttl < $ttl) {
165
+ $ttl = $rr->ttl;
166
+ }
167
+
168
+ $rr->rdata = '';
169
+ $rr->rdlength = 0;
170
+ }
171
+ foreach ($data->additional as $index => $rr) {
172
+
173
+ if ($rr->ttl < $ttl) {
174
+ $ttl = $rr->ttl;
175
+ }
176
+
177
+ $rr->rdata = '';
178
+ $rr->rdlength = 0;
179
+ }
180
+
181
+ $this->cache_data[$key] = array(
182
+
183
+ 'cache_date' => time(),
184
+ 'ttl' => $ttl
185
+ );
186
+
187
+ if ($this->cache_serializer == 'json') {
188
+ $this->cache_data[$key]['object'] = json_encode($data);
189
+ } else {
190
+ $this->cache_data[$key]['object'] = serialize($data);
191
+ }
192
+ }
193
+
194
+ /**
195
+ * runs a clean up process on the cache data
196
+ *
197
+ * @return void
198
+ * @access protected
199
+ *
200
+ */
201
+ protected function clean()
202
+ {
203
+ if (count($this->cache_data) > 0) {
204
+
205
+ //
206
+ // go through each entry and adjust their TTL, and remove entries that
207
+ // have expired
208
+ //
209
+ $now = time();
210
+
211
+ foreach ($this->cache_data as $key => $data) {
212
+
213
+ $diff = $now - $data['cache_date'];
214
+
215
+ if ($data['ttl'] <= $diff) {
216
+
217
+ unset($this->cache_data[$key]);
218
+ } else {
219
+
220
+ $this->cache_data[$key]['ttl'] -= $diff;
221
+ $this->cache_data[$key]['cache_date'] = $now;
222
+ }
223
+ }
224
+ }
225
+ }
226
+
227
+ /**
228
+ * runs a clean up process on the cache data
229
+ *
230
+ * @return mixed
231
+ * @access protected
232
+ *
233
+ */
234
+ protected function resize()
235
+ {
236
+ if (count($this->cache_data) > 0) {
237
+
238
+ //
239
+ // serialize the cache data
240
+ //
241
+ if ($this->cache_serializer == 'json') {
242
+ $cache = json_encode($this->cache_data);
243
+ } else {
244
+ $cache = serialize($this->cache_data);
245
+ }
246
+
247
+ //
248
+ // only do this part if the size allocated to the cache storage
249
+ // is smaller than the actual cache data
250
+ //
251
+ if (strlen($cache) > $this->cache_size) {
252
+
253
+ while (strlen($cache) > $this->cache_size) {
254
+
255
+ //
256
+ // go through the data, and remove the entries closed to
257
+ // their expiration date.
258
+ //
259
+ $smallest_ttl = time();
260
+ $smallest_key = null;
261
+
262
+ foreach ($this->cache_data as $key => $data) {
263
+
264
+ if ($data['ttl'] < $smallest_ttl) {
265
+
266
+ $smallest_ttl = $data['ttl'];
267
+ $smallest_key = $key;
268
+ }
269
+ }
270
+
271
+ //
272
+ // unset the key with the smallest TTL
273
+ //
274
+ unset($this->cache_data[$smallest_key]);
275
+
276
+ //
277
+ // re-serialize
278
+ //
279
+ if ($this->cache_serializer == 'json') {
280
+ $cache = json_encode($this->cache_data);
281
+ } else {
282
+ $cache = serialize($this->cache_data);
283
+ }
284
+ }
285
+ }
286
+
287
+ if ( ($cache == 'a:0:{}') || ($cache == '{}') ) {
288
+ return null;
289
+ } else {
290
+ return $cache;
291
+ }
292
+ }
293
+
294
+ return null;
295
+ }
296
+ };
297
+
298
+ /*
299
+ * Local variables:
300
+ * tab-width: 4
301
+ * c-basic-offset: 4
302
+ * c-hanging-comment-ender-p: nil
303
+ * End:
304
+ */
305
+ ?>
includes/Net/DNS2/Cache/File.php ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.1.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * File-based caching for the Net_DNS2_Cache class
54
+ *
55
+ * @category Networking
56
+ * @package Net_DNS2
57
+ * @author Mike Pultz <mike@mikepultz.com>
58
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
59
+ * @link http://pear.php.net/package/Net_DNS2
60
+ * @see Net_DNS2_Packet
61
+ *
62
+ */
63
+ class Net_DNS2_Cache_File extends Net_DNS2_Cache
64
+ {
65
+ /**
66
+ * open a cache object
67
+ *
68
+ * @param string $cache_file path to a file to use for cache storage
69
+ * @param integer $size the size of the shared memory segment to create
70
+ * @param string $serializer the name of the cache serialize to use
71
+ *
72
+ * @throws Net_DNS2_Exception
73
+ * @access public
74
+ * @return void
75
+ *
76
+ */
77
+ public function open($cache_file, $size, $serializer)
78
+ {
79
+ $this->cache_size = $size;
80
+ $this->cache_file = $cache_file;
81
+ $this->cache_serializer = $serializer;
82
+
83
+ //
84
+ // check that the file exists first
85
+ //
86
+ if ( (file_exists($this->cache_file) == true)
87
+ && (filesize($this->cache_file) > 0)
88
+ ) {
89
+
90
+ //
91
+ // open the file for reading
92
+ //
93
+ $fp = @fopen($this->cache_file, 'r');
94
+ if ($fp !== false) {
95
+
96
+ //
97
+ // lock the file just in case
98
+ //
99
+ flock($fp, LOCK_EX);
100
+
101
+ //
102
+ // read the file contents
103
+ //
104
+ $data = fread($fp, filesize($this->cache_file));
105
+
106
+ $decoded = null;
107
+
108
+ if ($this->cache_serializer == 'json') {
109
+
110
+ $decoded = json_decode($data, true);
111
+ } else {
112
+
113
+ $decoded = unserialize($data);
114
+ }
115
+
116
+ if (is_array($decoded) == true) {
117
+
118
+ $this->cache_data = $decoded;
119
+ } else {
120
+
121
+ $this->cache_data = array();
122
+ }
123
+
124
+ //
125
+ // unlock
126
+ //
127
+ flock($fp, LOCK_UN);
128
+
129
+ //
130
+ // close the file
131
+ //
132
+ fclose($fp);
133
+
134
+ //
135
+ // clean up the data
136
+ //
137
+ $this->clean();
138
+ }
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Destructor
144
+ *
145
+ * @access public
146
+ *
147
+ */
148
+ public function __destruct()
149
+ {
150
+ //
151
+ // if there's no cache file set, then there's nothing to do
152
+ //
153
+ if (strlen($this->cache_file) == 0) {
154
+ return;
155
+ }
156
+
157
+ //
158
+ // open the file for reading/writing
159
+ //
160
+ $fp = fopen($this->cache_file, 'a+');
161
+ if ($fp !== false) {
162
+
163
+ //
164
+ // lock the file just in case
165
+ //
166
+ flock($fp, LOCK_EX);
167
+
168
+ //
169
+ // seek to the start of the file to read
170
+ //
171
+ fseek($fp, 0, SEEK_SET);
172
+
173
+ //
174
+ // read the file contents
175
+ //
176
+ $data = @fread($fp, filesize($this->cache_file));
177
+ if ( ($data !== false) && (strlen($data) > 0) ) {
178
+
179
+ //
180
+ // unserialize and store the data
181
+ //
182
+ $c = $this->cache_data;
183
+
184
+ $decoded = null;
185
+
186
+ if ($this->cache_serializer == 'json') {
187
+
188
+ $decoded = json_decode($data, true);
189
+ } else {
190
+
191
+ $decoded = unserialize($data);
192
+ }
193
+
194
+ if (is_array($decoded) == true) {
195
+
196
+ $this->cache_data = array_merge($c, $decoded);
197
+ }
198
+ }
199
+
200
+ //
201
+ // trucate the file
202
+ //
203
+ ftruncate($fp, 0);
204
+
205
+ //
206
+ // clean the data
207
+ //
208
+ $this->clean();
209
+
210
+ //
211
+ // resize the data
212
+ //
213
+ $data = $this->resize();
214
+ if (!is_null($data)) {
215
+
216
+ //
217
+ // write the file contents
218
+ //
219
+ fwrite($fp, $data);
220
+ }
221
+
222
+ //
223
+ // unlock
224
+ //
225
+ flock($fp, LOCK_UN);
226
+
227
+ //
228
+ // close the file
229
+ //
230
+ fclose($fp);
231
+ }
232
+ }
233
+ };
234
+
235
+ /*
236
+ * Local variables:
237
+ * tab-width: 4
238
+ * c-basic-offset: 4
239
+ * c-hanging-comment-ender-p: nil
240
+ * End:
241
+ */
242
+ ?>
includes/Net/DNS2/Cache/Shm.php ADDED
@@ -0,0 +1,305 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.1.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * Shared Memory-based caching for the Net_DNS2_Cache class
54
+ *
55
+ * @category Networking
56
+ * @package Net_DNS2
57
+ * @author Mike Pultz <mike@mikepultz.com>
58
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
59
+ * @link http://pear.php.net/package/Net_DNS2
60
+ * @see Net_DNS2_Packet
61
+ *
62
+ */
63
+ class Net_DNS2_Cache_Shm extends Net_DNS2_Cache
64
+ {
65
+ /*
66
+ * resource id of the shared memory cache
67
+ */
68
+ private $_cache_id = false;
69
+
70
+ /*
71
+ * the IPC key
72
+ */
73
+ private $_cache_file_tok = -1;
74
+
75
+ /**
76
+ * open a cache object
77
+ *
78
+ * @param string $cache_file path to a file to use for cache storage
79
+ * @param integer $size the size of the shared memory segment to create
80
+ * @param string $serializer the name of the cache serialize to use
81
+ *
82
+ * @throws Net_DNS2_Exception
83
+ * @access public
84
+ * @return void
85
+ *
86
+ */
87
+ public function open($cache_file, $size, $serializer)
88
+ {
89
+ $this->cache_size = $size;
90
+ $this->cache_file = $cache_file;
91
+ $this->cache_serializer = $serializer;
92
+
93
+ //
94
+ // make sure the file exists first
95
+ //
96
+ if (!file_exists($cache_file)) {
97
+
98
+ if (file_put_contents($cache_file, '') === false) {
99
+
100
+ throw new Net_DNS2_Exception(
101
+ 'failed to create empty SHM file: ' . $cache_file,
102
+ Net_DNS2_Lookups::E_CACHE_SHM_FILE
103
+ );
104
+ }
105
+ }
106
+
107
+ //
108
+ // convert the filename to a IPC key
109
+ //
110
+ $this->_cache_file_tok = ftok($cache_file, 't');
111
+ if ($this->_cache_file_tok == -1) {
112
+
113
+ throw new Net_DNS2_Exception(
114
+ 'failed on ftok() file: ' . $this->_cache_file_tok,
115
+ Net_DNS2_Lookups::E_CACHE_SHM_FILE
116
+ );
117
+ }
118
+
119
+ //
120
+ // try to open an existing cache; if it doesn't exist, then there's no
121
+ // cache, and nothing to do.
122
+ //
123
+ $this->_cache_id = @shmop_open($this->_cache_file_tok, 'w', 0, 0);
124
+ if ($this->_cache_id !== false) {
125
+
126
+ //
127
+ // this returns the size allocated, and not the size used, but it's
128
+ // still a good check to make sure there's space allocated.
129
+ //
130
+ $allocated = shmop_size($this->_cache_id);
131
+ if ($allocated > 0) {
132
+
133
+ //
134
+ // read the data from the shared memory segment
135
+ //
136
+ $data = trim(shmop_read($this->_cache_id, 0, $allocated));
137
+ if ( ($data !== false) && (strlen($data) > 0) ) {
138
+
139
+ //
140
+ // unserialize and store the data
141
+ //
142
+ $decoded = null;
143
+
144
+ if ($this->cache_serializer == 'json') {
145
+
146
+ $decoded = json_decode($data, true);
147
+ } else {
148
+
149
+ $decoded = unserialize($data);
150
+ }
151
+
152
+ if (is_array($decoded) == true) {
153
+
154
+ $this->cache_data = $decoded;
155
+ } else {
156
+
157
+ $this->cache_data = array();
158
+ }
159
+
160
+ //
161
+ // call clean to clean up old entries
162
+ //
163
+ $this->clean();
164
+ }
165
+ }
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Destructor
171
+ *
172
+ * @access public
173
+ *
174
+ */
175
+ public function __destruct()
176
+ {
177
+ //
178
+ // if there's no cache file set, then there's nothing to do
179
+ //
180
+ if (strlen($this->cache_file) == 0) {
181
+ return;
182
+ }
183
+
184
+ $fp = fopen($this->cache_file, 'r');
185
+ if ($fp !== false) {
186
+
187
+ //
188
+ // lock the file
189
+ //
190
+ flock($fp, LOCK_EX);
191
+
192
+ //
193
+ // check to see if we have an open shm segment
194
+ //
195
+ if ($this->_cache_id === false) {
196
+
197
+ //
198
+ // try opening it again, incase it was created by another
199
+ // process in the mean time
200
+ //
201
+ $this->_cache_id = @shmop_open(
202
+ $this->_cache_file_tok, 'w', 0, 0
203
+ );
204
+ if ($this->_cache_id === false) {
205
+
206
+ //
207
+ // otherwise, create it.
208
+ //
209
+ $this->_cache_id = @shmop_open(
210
+ $this->_cache_file_tok, 'c', 0, $this->cache_size
211
+ );
212
+ }
213
+ }
214
+
215
+ //
216
+ // get the size allocated to the segment
217
+ //
218
+ $allocated = shmop_size($this->_cache_id);
219
+
220
+ //
221
+ // read the contents
222
+ //
223
+ $data = trim(shmop_read($this->_cache_id, 0, $allocated));
224
+
225
+ //
226
+ // if there was some data
227
+ //
228
+ if ( ($data !== false) && (strlen($data) > 0) ) {
229
+
230
+ //
231
+ // unserialize and store the data
232
+ //
233
+ $c = $this->cache_data;
234
+
235
+ $decoded = null;
236
+
237
+ if ($this->cache_serializer == 'json') {
238
+
239
+ $decoded = json_decode($data, true);
240
+ } else {
241
+
242
+ $decoded = unserialize($data);
243
+ }
244
+
245
+ if (is_array($decoded) == true) {
246
+
247
+ $this->cache_data = array_merge($c, $decoded);
248
+ }
249
+ }
250
+
251
+ //
252
+ // delete the segment
253
+ //
254
+ shmop_delete($this->_cache_id);
255
+
256
+ //
257
+ // clean the data
258
+ //
259
+ $this->clean();
260
+
261
+ //
262
+ // clean up and write the data
263
+ //
264
+ $data = $this->resize();
265
+ if (!is_null($data)) {
266
+
267
+ //
268
+ // re-create segment
269
+ //
270
+ $this->_cache_id = @shmop_open(
271
+ $this->_cache_file_tok, 'c', 0644, $this->cache_size
272
+ );
273
+ if ($this->_cache_id === false) {
274
+ return;
275
+ }
276
+
277
+ $o = shmop_write($this->_cache_id, $data, 0);
278
+ }
279
+
280
+ //
281
+ // close the segment
282
+ //
283
+ shmop_close($this->_cache_id);
284
+
285
+ //
286
+ // unlock
287
+ //
288
+ flock($fp, LOCK_UN);
289
+
290
+ //
291
+ // close the file
292
+ //
293
+ fclose($fp);
294
+ }
295
+ }
296
+ };
297
+
298
+ /*
299
+ * Local variables:
300
+ * tab-width: 4
301
+ * c-basic-offset: 4
302
+ * c-hanging-comment-ender-p: nil
303
+ * End:
304
+ */
305
+ ?>
includes/Net/DNS2/Exception.php ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ */
50
+
51
+ /**
52
+ * Exception handler used by Net_DNS2
53
+ *
54
+ * @category Networking
55
+ * @package Net_DNS2
56
+ * @author Mike Pultz <mike@mikepultz.com>
57
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
58
+ * @link http://pear.php.net/package/Net_DNS2
59
+ *
60
+ */
61
+ class Net_DNS2_Exception extends Exception
62
+ {
63
+ private $_request;
64
+ private $_response;
65
+
66
+ /**
67
+ * Constructor - overload the constructor so we can pass in the request
68
+ * and response object (when it's available)
69
+ *
70
+ * @param string $message the exception message
71
+ * @param int $code the exception code
72
+ * @param object $previous the previous Exception object
73
+ * @param object $request the Net_DNS2_Packet_Request object for this request
74
+ * @param object $response the Net_DNS2_Packet_Response object for this request
75
+ *
76
+ * @access public
77
+ *
78
+ */
79
+ public function __construct(
80
+ $message = '',
81
+ $code = 0,
82
+ $previous = null,
83
+ Net_DNS2_Packet_Request $request = null,
84
+ Net_DNS2_Packet_Response $response = null
85
+ ) {
86
+ //
87
+ // store the request/response objects (if passed)
88
+ //
89
+ $this->_request = $request;
90
+ $this->_response = $response;
91
+
92
+ //
93
+ // call the parent constructor
94
+ //
95
+ // the "previous" argument was added in PHP 5.3.0
96
+ //
97
+ // https://code.google.com/p/netdns2/issues/detail?id=25
98
+ //
99
+ if (version_compare(PHP_VERSION, '5.3.0', '>=') == true) {
100
+
101
+ parent::__construct($message, $code, $previous);
102
+ } else {
103
+
104
+ parent::__construct($message, $code);
105
+ }
106
+ }
107
+
108
+ /**
109
+ * returns the Net_DNS2_Packet_Request object (if available)
110
+ *
111
+ * @return Net_DNS2_Packet_Request object
112
+ * @access public
113
+ * @since function available since release 1.3.1
114
+ *
115
+ */
116
+ public function getRequest()
117
+ {
118
+ return $this->_request;
119
+ }
120
+
121
+ /**
122
+ * returns the Net_DNS2_Packet_Response object (if available)
123
+ *
124
+ * @return Net_DNS2_Packet_Response object
125
+ * @access public
126
+ * @since function available since release 1.3.1
127
+ *
128
+ */
129
+ public function getResponse()
130
+ {
131
+ return $this->_response;
132
+ }
133
+ }
134
+
135
+ /*
136
+ * Local variables:
137
+ * tab-width: 4
138
+ * c-basic-offset: 4
139
+ * c-hanging-comment-ender-p: nil
140
+ * End:
141
+ */
142
+ ?>
includes/Net/DNS2/Header.php ADDED
@@ -0,0 +1,282 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+
53
+ /**
54
+ * DNS Packet Header class
55
+ *
56
+ * This class handles parsing and constructing DNS Packet Headers as defined
57
+ * by section 4.1.1 of RFC1035.
58
+ *
59
+ * DNS header format - RFC1035 section 4.1.1
60
+ * DNS header format - RFC4035 section 3.2
61
+ *
62
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
63
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
64
+ * | ID |
65
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
66
+ * |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE |
67
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
68
+ * | QDCOUNT |
69
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
70
+ * | ANCOUNT |
71
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
72
+ * | NSCOUNT |
73
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
74
+ * | ARCOUNT |
75
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
76
+ *
77
+ * @category Networking
78
+ * @package Net_DNS2
79
+ * @author Mike Pultz <mike@mikepultz.com>
80
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
81
+ * @link http://pear.php.net/package/Net_DNS2
82
+ *
83
+ */
84
+ class Net_DNS2_Header
85
+ {
86
+ public $id; // 16 bit - identifier
87
+ public $qr; // 1 bit - 0 = query, 1 = response
88
+ public $opcode; // 4 bit - op code
89
+ public $aa; // 1 bit - Authoritative Answer
90
+ public $tc; // 1 bit - TrunCation
91
+ public $rd; // 1 bit - Recursion Desired
92
+ public $ra; // 1 bit - Recursion Available
93
+ public $z; // 1 bit - Reserved
94
+ public $ad; // 1 bit - Authentic Data (RFC4035)
95
+ public $cd; // 1 bit - Checking Disabled (RFC4035)
96
+ public $rcode; // 4 bit - Response code
97
+ public $qdcount; // 16 bit - entries in the question section
98
+ public $ancount; // 16 bit - resource records in the answer section
99
+ public $nscount; // 16 bit - name server rr in the authority records section
100
+ public $arcount; // 16 bit - rr's in the additional records section
101
+
102
+ /**
103
+ * Constructor - builds a new Net_DNS2_Header object
104
+ *
105
+ * @param mixed &$packet either a Net_DNS2_Packet object or null
106
+ *
107
+ * @throws Net_DNS2_Exception
108
+ * @access public
109
+ *
110
+ */
111
+ public function __construct(Net_DNS2_Packet &$packet = null)
112
+ {
113
+ if (!is_null($packet)) {
114
+
115
+ $this->set($packet);
116
+ } else {
117
+
118
+ $this->id = $this->nextPacketId();
119
+ $this->qr = Net_DNS2_Lookups::QR_QUERY;
120
+ $this->opcode = Net_DNS2_Lookups::OPCODE_QUERY;
121
+ $this->aa = 0;
122
+ $this->tc = 0;
123
+ $this->rd = 1;
124
+ $this->ra = 0;
125
+ $this->z = 0;
126
+ $this->ad = 0;
127
+ $this->cd = 0;
128
+ $this->rcode = Net_DNS2_Lookups::RCODE_NOERROR;
129
+ $this->qdcount = 1;
130
+ $this->ancount = 0;
131
+ $this->nscount = 0;
132
+ $this->arcount = 0;
133
+ }
134
+ }
135
+
136
+ /**
137
+ * returns the next available packet id
138
+ *
139
+ * @return integer
140
+ * @access public
141
+ *
142
+ */
143
+ public function nextPacketId()
144
+ {
145
+ if (++Net_DNS2_Lookups::$next_packet_id > 65535) {
146
+
147
+ Net_DNS2_Lookups::$next_packet_id = 1;
148
+ }
149
+
150
+ return Net_DNS2_Lookups::$next_packet_id;
151
+ }
152
+
153
+ /**
154
+ * magic __toString() method to return the header as a string
155
+ *
156
+ * @return string
157
+ * @access public
158
+ *
159
+ */
160
+ public function __toString()
161
+ {
162
+ $output = ";;\n;; Header:\n";
163
+
164
+ $output .= ";;\t id = " . $this->id . "\n";
165
+ $output .= ";;\t qr = " . $this->qr . "\n";
166
+ $output .= ";;\t opcode = " . $this->opcode . "\n";
167
+ $output .= ";;\t aa = " . $this->aa . "\n";
168
+ $output .= ";;\t tc = " . $this->tc . "\n";
169
+ $output .= ";;\t rd = " . $this->rd . "\n";
170
+ $output .= ";;\t ra = " . $this->ra . "\n";
171
+ $output .= ";;\t z = " . $this->z . "\n";
172
+ $output .= ";;\t ad = " . $this->ad . "\n";
173
+ $output .= ";;\t cd = " . $this->cd . "\n";
174
+ $output .= ";;\t rcode = " . $this->rcode . "\n";
175
+ $output .= ";;\t qdcount = " . $this->qdcount . "\n";
176
+ $output .= ";;\t ancount = " . $this->ancount . "\n";
177
+ $output .= ";;\t nscount = " . $this->nscount . "\n";
178
+ $output .= ";;\t arcount = " . $this->arcount . "\n";
179
+
180
+ return $output;
181
+ }
182
+
183
+ /**
184
+ * constructs a Net_DNS2_Header from a Net_DNS2_Packet object
185
+ *
186
+ * @param Net_DNS2_Packet &$packet Object
187
+ *
188
+ * @return boolean
189
+ * @throws Net_DNS2_Exception
190
+ * @access public
191
+ *
192
+ */
193
+ public function set(Net_DNS2_Packet &$packet)
194
+ {
195
+ //
196
+ // the header must be at least 12 bytes long.
197
+ //
198
+ if ($packet->rdlength < Net_DNS2_Lookups::DNS_HEADER_SIZE) {
199
+
200
+ throw new Net_DNS2_Exception(
201
+ 'invalid header data provided; to small',
202
+ Net_DNS2_Lookups::E_HEADER_INVALID
203
+ );
204
+ }
205
+
206
+ $offset = 0;
207
+
208
+ //
209
+ // parse the values
210
+ //
211
+ $this->id = ord($packet->rdata[$offset]) << 8 |
212
+ ord($packet->rdata[++$offset]);
213
+
214
+ ++$offset;
215
+ $this->qr = (ord($packet->rdata[$offset]) >> 7) & 0x1;
216
+ $this->opcode = (ord($packet->rdata[$offset]) >> 3) & 0xf;
217
+ $this->aa = (ord($packet->rdata[$offset]) >> 2) & 0x1;
218
+ $this->tc = (ord($packet->rdata[$offset]) >> 1) & 0x1;
219
+ $this->rd = ord($packet->rdata[$offset]) & 0x1;
220
+
221
+ ++$offset;
222
+ $this->ra = (ord($packet->rdata[$offset]) >> 7) & 0x1;
223
+ $this->z = (ord($packet->rdata[$offset]) >> 6) & 0x1;
224
+ $this->ad = (ord($packet->rdata[$offset]) >> 5) & 0x1;
225
+ $this->cd = (ord($packet->rdata[$offset]) >> 4) & 0x1;
226
+ $this->rcode = ord($packet->rdata[$offset]) & 0xf;
227
+
228
+ $this->qdcount = ord($packet->rdata[++$offset]) << 8 |
229
+ ord($packet->rdata[++$offset]);
230
+ $this->ancount = ord($packet->rdata[++$offset]) << 8 |
231
+ ord($packet->rdata[++$offset]);
232
+ $this->nscount = ord($packet->rdata[++$offset]) << 8 |
233
+ ord($packet->rdata[++$offset]);
234
+ $this->arcount = ord($packet->rdata[++$offset]) << 8 |
235
+ ord($packet->rdata[++$offset]);
236
+
237
+ //
238
+ // increment the internal offset
239
+ //
240
+ $packet->offset += Net_DNS2_Lookups::DNS_HEADER_SIZE;
241
+
242
+ return true;
243
+ }
244
+
245
+ /**
246
+ * returns a binary packed DNS Header
247
+ *
248
+ * @param Net_DNS2_Packet &$packet Object
249
+ *
250
+ * @return string
251
+ * @access public
252
+ *
253
+ */
254
+ public function get(Net_DNS2_Packet &$packet)
255
+ {
256
+ $data = pack('n', $this->id) .
257
+ chr(
258
+ ($this->qr << 7) | ($this->opcode << 3) |
259
+ ($this->aa << 2) | ($this->tc << 1) | ($this->rd)
260
+ ) .
261
+ chr(
262
+ ($this->ra << 7) | ($this->ad << 5) | ($this->cd << 4) | $this->rcode
263
+ ) .
264
+ chr($this->qdcount << 8) . chr($this->qdcount) .
265
+ chr($this->ancount << 8) . chr($this->ancount) .
266
+ chr($this->nscount << 8) . chr($this->nscount) .
267
+ chr($this->arcount << 8) . chr($this->arcount);
268
+
269
+ $packet->offset += Net_DNS2_Lookups::DNS_HEADER_SIZE;
270
+
271
+ return $data;
272
+ }
273
+ }
274
+
275
+ /*
276
+ * Local variables:
277
+ * tab-width: 4
278
+ * c-basic-offset: 4
279
+ * c-hanging-comment-ender-p: nil
280
+ * End:
281
+ */
282
+ ?>
includes/Net/DNS2/Lookups.php ADDED
@@ -0,0 +1,552 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ //
53
+ // initalize the packet id value
54
+ //
55
+ Net_DNS2_Lookups::$next_packet_id = mt_rand(0, 65535);
56
+
57
+ //
58
+ // build the reverse lookup tables; this is just so we don't have to
59
+ // have duplicate static content laying around.
60
+ //
61
+ Net_DNS2_Lookups::$rr_types_by_id = array_flip(Net_DNS2_Lookups::$rr_types_by_name);
62
+ Net_DNS2_Lookups::$classes_by_id = array_flip(Net_DNS2_Lookups::$classes_by_name);
63
+ Net_DNS2_Lookups::$rr_types_class_to_id = array_flip(Net_DNS2_Lookups::$rr_types_id_to_class);
64
+ Net_DNS2_Lookups::$algorithm_name_to_id = array_flip(Net_DNS2_Lookups::$algorithm_id_to_name);
65
+ Net_DNS2_Lookups::$digest_name_to_id = array_flip(Net_DNS2_Lookups::$digest_id_to_name);
66
+ Net_DNS2_Lookups::$rr_qtypes_by_id = array_flip(Net_DNS2_Lookups::$rr_qtypes_by_name);
67
+ Net_DNS2_Lookups::$rr_metatypes_by_id = array_flip(Net_DNS2_Lookups::$rr_metatypes_by_name);
68
+ Net_DNS2_Lookups::$protocol_by_id = array_flip(Net_DNS2_Lookups::$protocol_by_name);
69
+
70
+ /**
71
+ * This class provides simple lookups used througout the Net_DNS2 code
72
+ *
73
+ * @category Networking
74
+ * @package Net_DNS2
75
+ * @author Mike Pultz <mike@mikepultz.com>
76
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
77
+ * @link http://pear.php.net/package/Net_DNS2
78
+ *
79
+ */
80
+ class Net_DNS2_Lookups
81
+ {
82
+ /*
83
+ * size (in bytes) of a header in a standard DNS packet
84
+ */
85
+ const DNS_HEADER_SIZE = 12;
86
+
87
+ /*
88
+ * max size of a UDP packet
89
+ */
90
+ const DNS_MAX_UDP_SIZE = 512;
91
+
92
+ /*
93
+ * Query/Response flag
94
+ */
95
+ const QR_QUERY = 0; // RFC 1035
96
+ const QR_RESPONSE = 1; // RFC 1035
97
+
98
+ /*
99
+ * DNS Op Codes
100
+ */
101
+ const OPCODE_QUERY = 0; // RFC 1035
102
+ const OPCODE_IQUERY = 1; // RFC 1035, RFC 3425
103
+ const OPCODE_STATUS = 2; // RFC 1035
104
+ const OPCODE_NOTIFY = 4; // RFC 1996
105
+ const OPCODE_UPDATE = 5; // RFC 2136
106
+
107
+ /*
108
+ * Resource Record Classes
109
+ */
110
+ const RR_CLASS_IN = 1; // RFC 1035
111
+ const RR_CLASS_CH = 3; // RFC 1035
112
+ const RR_CLASS_HS = 4; // RFC 1035
113
+ const RR_CLASS_NONE = 254; // RFC 2136
114
+ const RR_CLASS_ANY = 255; // RFC 1035
115
+
116
+ /*
117
+ * DNS Response Codes
118
+ */
119
+ const RCODE_NOERROR = 0; // RFC 1035
120
+ const RCODE_FORMERR = 1; // RFC 1035
121
+ const RCODE_SERVFAIL = 2; // RFC 1035
122
+ const RCODE_NXDOMAIN = 3; // RFC 1035
123
+ const RCODE_NOTIMP = 4; // RFC 1035
124
+ const RCODE_REFUSED = 5; // RFC 1035
125
+ const RCODE_YXDOMAIN = 6; // RFC 2136
126
+ const RCODE_YXRRSET = 7; // RFC 2136
127
+ const RCODE_NXRRSET = 8; // RFC 2136
128
+ const RCODE_NOTAUTH = 9; // RFC 2136
129
+ const RCODE_NOTZONE = 10; // RFC 2136
130
+
131
+ // 11-15 reserved
132
+
133
+ const RCODE_BADSIG = 16; // RFC 2845
134
+ const RCODE_BADKEY = 17; // RFC 2845
135
+ const RCODE_BADTIME = 18; // RFC 2845
136
+ const RCODE_BADMODE = 19; // RFC 2930
137
+ const RCODE_BADNAME = 20; // RFC 2930
138
+ const RCODE_BADALG = 21; // RFC 2930
139
+ const RCODE_BADTRUNC = 22; // RFC 4635
140
+
141
+ /*
142
+ * internal errors codes returned by the exceptions class
143
+ */
144
+ const E_NONE = 0;
145
+ const E_DNS_FORMERR = self::RCODE_FORMERR;
146
+ const E_DNS_SERVFAIL = self::RCODE_SERVFAIL;
147
+ const E_DNS_NXDOMAIN = self::RCODE_NXDOMAIN;
148
+ const E_DNS_NOTIMP = self::RCODE_NOTIMP;
149
+ const E_DNS_REFUSED = self::RCODE_REFUSED;
150
+ const E_DNS_YXDOMAIN = self::RCODE_YXDOMAIN;
151
+ const E_DNS_YXRRSET = self::RCODE_YXRRSET;
152
+ const E_DNS_NXRRSET = self::RCODE_NXRRSET;
153
+ const E_DNS_NOTAUTH = self::RCODE_NOTAUTH;
154
+ const E_DNS_NOTZONE = self::RCODE_NOTZONE;
155
+
156
+ // 11-15 reserved
157
+
158
+ const E_DNS_BADSIG = self::RCODE_BADSIG;
159
+ const E_DNS_BADKEY = self::RCODE_BADKEY;
160
+ const E_DNS_BADTIME = self::RCODE_BADTIME;
161
+ const E_DNS_BADMODE = self::RCODE_BADMODE;
162
+ const E_DNS_BADNAME = self::RCODE_BADNAME;
163
+ const E_DNS_BADALG = self::RCODE_BADALG;
164
+ const E_DNS_BADTRUNC = self::RCODE_BADTRUNC;
165
+
166
+ // other error conditions
167
+
168
+ const E_NS_INVALID_FILE = 200;
169
+ const E_NS_INVALID_ENTRY = 201;
170
+ const E_NS_FAILED = 202;
171
+ const E_NS_SOCKET_FAILED = 203;
172
+
173
+ const E_PACKET_INVALID = 300;
174
+ const E_PARSE_ERROR = 301;
175
+ const E_HEADER_INVALID = 302;
176
+ const E_QUESTION_INVALID = 303;
177
+ const E_RR_INVALID = 304;
178
+
179
+ const E_OPENSSL_ERROR = 400;
180
+ const E_OPENSSL_UNAVAIL = 401;
181
+ const E_OPENSSL_INV_PKEY = 402;
182
+ const E_OPENSSL_INV_ALGO = 403;
183
+
184
+ const E_CACHE_UNSUPPORTED = 500;
185
+ const E_CACHE_SHM_FILE = 501;
186
+ const E_CACHE_SHM_UNAVAIL = 502;
187
+
188
+ /*
189
+ * DNSSEC Algorithms
190
+ */
191
+ const DNSSEC_ALGORITHM_RES = 0;
192
+ const DNSSEC_ALGORITHM_RSAMD5 = 1;
193
+ const DNSSEC_ALGORITHM_DH = 2;
194
+ const DNSSEC_ALGORITHM_DSA = 3;
195
+ const DNSSEC_ALGORITHM_ECC = 4;
196
+ const DNSSEC_ALGORITHM_RSASHA1 = 5;
197
+ const DNSSEC_ALGORITHM_DSANSEC3SHA1 = 6;
198
+ const DSNSEC_ALGORITHM_RSASHA1NSEC3SHA1 = 7;
199
+ const DNSSEC_ALGORITHM_RSASHA256 = 8;
200
+ const DNSSEC_ALGORITHM_RSASHA512 = 10;
201
+ const DNSSEC_ALGORITHM_ECCGOST = 12;
202
+ const DNSSEC_ALGORITHM_INDIRECT = 252;
203
+ const DNSSEC_ALGORITHM_PRIVATEDNS = 253;
204
+ const DNSSEC_ALGORITHM_PRIVATEOID = 254;
205
+
206
+ /*
207
+ * DNSSEC Digest Types
208
+ */
209
+ const DNSSEC_DIGEST_RES = 0;
210
+ const DNSSEC_DIGEST_SHA1 = 1;
211
+
212
+ /*
213
+ * The packet id used when sending requests
214
+ */
215
+ public static $next_packet_id;
216
+
217
+ /*
218
+ * Used to map resource record types to their id's, and back
219
+ */
220
+ public static $rr_types_by_id = array();
221
+ public static $rr_types_by_name = array(
222
+
223
+ 'SIG0' => 0, // RFC 2931 pseudo type
224
+ 'A' => 1, // RFC 1035
225
+ 'NS' => 2, // RFC 1035
226
+ 'MD' => 3, // RFC 1035 - obsolete, Not implemented
227
+ 'MF' => 4, // RFC 1035 - obsolete, Not implemented
228
+ 'CNAME' => 5, // RFC 1035
229
+ 'SOA' => 6, // RFC 1035
230
+ 'MB' => 7, // RFC 1035 - obsolete, Not implemented
231
+ 'MG' => 8, // RFC 1035 - obsolete, Not implemented
232
+ 'MR' => 9, // RFC 1035 - obsolete, Not implemented
233
+ 'NULL' => 10, // RFC 1035 - obsolete, Not implemented
234
+ 'WKS' => 11, // RFC 1035
235
+ 'PTR' => 12, // RFC 1035
236
+ 'HINFO' => 13, // RFC 1035
237
+ 'MINFO' => 14, // RFC 1035 - obsolete, Not implemented
238
+ 'MX' => 15, // RFC 1035
239
+ 'TXT' => 16, // RFC 1035
240
+ 'RP' => 17, // RFC 1183
241
+ 'AFSDB' => 18, // RFC 1183
242
+ 'X25' => 19, // RFC 1183
243
+ 'ISDN' => 20, // RFC 1183
244
+ 'RT' => 21, // RFC 1183
245
+ 'NSAP' => 22, // RFC 1706
246
+ 'NSAP_PTR' => 23, // RFC 1348 - obsolete, Not implemented
247
+ 'SIG' => 24, // RFC 2535
248
+ 'KEY' => 25, // RFC 2535, RFC 2930
249
+ 'PX' => 26, // RFC 2163
250
+ 'GPOS' => 27, // RFC 1712 - Not implemented
251
+ 'AAAA' => 28, // RFC 3596
252
+ 'LOC' => 29, // RFC 1876
253
+ 'NXT' => 30, // RFC 2065, obsoleted by by RFC 3755
254
+ 'EID' => 31, // [Patton][Patton1995]
255
+ 'NIMLOC' => 32, // [Patton][Patton1995]
256
+ 'SRV' => 33, // RFC 2782
257
+ 'ATMA' => 34, // Windows only
258
+ 'NAPTR' => 35, // RFC 2915
259
+ 'KX' => 36, // RFC 2230
260
+ 'CERT' => 37, // RFC 4398
261
+ 'A6' => 38, // downgraded to experimental by RFC 3363
262
+ 'DNAME' => 39, // RFC 2672
263
+ 'SINK' => 40, // Not implemented
264
+ 'OPT' => 41, // RFC 2671
265
+ 'APL' => 42, // RFC 3123
266
+ 'DS' => 43, // RFC 4034
267
+ 'SSHFP' => 44, // RFC 4255
268
+ 'IPSECKEY' => 45, // RFC 4025
269
+ 'RRSIG' => 46, // RFC 4034
270
+ 'NSEC' => 47, // RFC 4034
271
+ 'DNSKEY' => 48, // RFC 4034
272
+ 'DHCID' => 49, // RFC 4701
273
+ 'NSEC3' => 50, // RFC 5155
274
+ 'NSEC3PARAM' => 51, // RFC 5155
275
+ 'TLSA' => 52, // RFC 6698
276
+
277
+ // 53 - 54 unassigned
278
+
279
+ 'HIP' => 55, // RFC 5205
280
+ 'NINFO' => 56, // Not implemented
281
+ 'RKEY' => 57, // Not implemented
282
+ 'TALINK' => 58, //
283
+ 'CDS' => 59, // RFC 7344
284
+ 'CDNSKEY' => 60, // RFC 7344
285
+ 'OPENPGPKEY' => 61, // IETF (draft-ietf-dane-openpgpkey)
286
+ 'CSYNC' => 62, // RFC 7477
287
+
288
+ // 63 - 98 unassigned
289
+
290
+ 'SPF' => 99, // RFC 4408
291
+ 'UINFO' => 100, // no RFC, Not implemented
292
+ 'UID' => 101, // no RFC, Not implemented
293
+ 'GID' => 102, // no RFC, Not implemented
294
+ 'UNSPEC' => 103, // no RFC, Not implemented
295
+ 'NID' => 104, // RFC 6742
296
+ 'L32' => 105, // RFC 6742
297
+ 'L64' => 106, // RFC 6742
298
+ 'LP' => 107, // RFC 6742
299
+ 'EUI48' => 108, // RFC 7043
300
+ 'EUI64' => 109, // RFC 7043
301
+
302
+ // 110 - 248 unassigned
303
+
304
+ 'TKEY' => 249, // RFC 2930
305
+ 'TSIG' => 250, // RFC 2845
306
+ 'IXFR' => 251, // RFC 1995 - only a full (AXFR) is supported
307
+ 'AXFR' => 252, // RFC 1035
308
+ 'MAILB' => 253, // RFC 883, Not implemented
309
+ 'MAILA' => 254, // RFC 973, Not implemented
310
+ 'ANY' => 255, // RFC 1035 - we support both 'ANY' and '*'
311
+ 'URI' => 256, // tools.ietf.org/html/draft-faltstrom-uri-06
312
+ 'CAA' => 257, // tools.ietf.org/html/draft-ietf-pkix-caa-03
313
+
314
+ // 258 - 32767 unassigned
315
+
316
+ 'TA' => 32768, // same as DS
317
+ 'DLV' => 32769 // RFC 4431
318
+ );
319
+
320
+ /*
321
+ * Qtypes and Metatypes - defined in RFC2929 section 3.1
322
+ */
323
+ public static $rr_qtypes_by_id = array();
324
+ public static $rr_qtypes_by_name = array(
325
+
326
+ 'IXFR' => 251, // RFC 1995 - only a full (AXFR) is supported
327
+ 'AXFR' => 252, // RFC 1035
328
+ 'MAILB' => 253, // RFC 883, Not implemented
329
+ 'MAILA' => 254, // RFC 973, Not implemented
330
+ 'ANY' => 255 // RFC 1035 - we support both 'ANY' and '*'
331
+ );
332
+
333
+ public static $rr_metatypes_by_id = array();
334
+ public static $rr_metatypes_by_name = array(
335
+
336
+ 'OPT' => 41, // RFC 2671
337
+ 'TKEY' => 249, // RFC 2930
338
+ 'TSIG' => 250 // RFC 2845
339
+ );
340
+
341
+ /*
342
+ * used to map resource record id's to RR class names
343
+ */
344
+ public static $rr_types_class_to_id = array();
345
+ public static $rr_types_id_to_class = array(
346
+
347
+ 1 => 'Net_DNS2_RR_A',
348
+ 2 => 'Net_DNS2_RR_NS',
349
+ 5 => 'Net_DNS2_RR_CNAME',
350
+ 6 => 'Net_DNS2_RR_SOA',
351
+ 11 => 'Net_DNS2_RR_WKS',
352
+ 12 => 'Net_DNS2_RR_PTR',
353
+ 13 => 'Net_DNS2_RR_HINFO',
354
+ 15 => 'Net_DNS2_RR_MX',
355
+ 16 => 'Net_DNS2_RR_TXT',
356
+ 17 => 'Net_DNS2_RR_RP',
357
+ 18 => 'Net_DNS2_RR_AFSDB',
358
+ 19 => 'Net_DNS2_RR_X25',
359
+ 20 => 'Net_DNS2_RR_ISDN',
360
+ 21 => 'Net_DNS2_RR_RT',
361
+ 22 => 'Net_DNS2_RR_NSAP',
362
+ 24 => 'Net_DNS2_RR_SIG',
363
+ 25 => 'Net_DNS2_RR_KEY',
364
+ 26 => 'Net_DNS2_RR_PX',
365
+ 28 => 'Net_DNS2_RR_AAAA',
366
+ 29 => 'Net_DNS2_RR_LOC',
367
+ 31 => 'Net_DNS2_RR_EID',
368
+ 32 => 'Net_DNS2_RR_NIMLOC',
369
+ 33 => 'Net_DNS2_RR_SRV',
370
+ 34 => 'Net_DNS2_RR_ATMA',
371
+ 35 => 'Net_DNS2_RR_NAPTR',
372
+ 36 => 'Net_DNS2_RR_KX',
373
+ 37 => 'Net_DNS2_RR_CERT',
374
+ 39 => 'Net_DNS2_RR_DNAME',
375
+ 41 => 'Net_DNS2_RR_OPT',
376
+ 42 => 'Net_DNS2_RR_APL',
377
+ 43 => 'Net_DNS2_RR_DS',
378
+ 44 => 'Net_DNS2_RR_SSHFP',
379
+ 45 => 'Net_DNS2_RR_IPSECKEY',
380
+ 46 => 'Net_DNS2_RR_RRSIG',
381
+ 47 => 'Net_DNS2_RR_NSEC',
382
+ 48 => 'Net_DNS2_RR_DNSKEY',
383
+ 49 => 'Net_DNS2_RR_DHCID',
384
+ 50 => 'Net_DNS2_RR_NSEC3',
385
+ 51 => 'Net_DNS2_RR_NSEC3PARAM',
386
+ 52 => 'Net_DNS2_RR_TLSA',
387
+ 55 => 'Net_DNS2_RR_HIP',
388
+ 58 => 'Net_DNS2_RR_TALINK',
389
+ 59 => 'Net_DNS2_RR_CDS',
390
+ 60 => 'Net_DNS2_RR_CDNSKEY',
391
+ 61 => 'Net_DNS2_RR_OPENPGPKEY',
392
+ 62 => 'Net_DNS2_RR_CSYNC',
393
+ 99 => 'Net_DNS2_RR_SPF',
394
+ 104 => 'Net_DNS2_RR_NID',
395
+ 105 => 'Net_DNS2_RR_L32',
396
+ 106 => 'Net_DNS2_RR_L64',
397
+ 107 => 'Net_DNS2_RR_LP',
398
+ 108 => 'Net_DNS2_RR_EUI48',
399
+ 109 => 'Net_DNS2_RR_EUI64',
400
+
401
+ 249 => 'Net_DNS2_RR_TKEY',
402
+ 250 => 'Net_DNS2_RR_TSIG',
403
+
404
+ // 251 - IXFR - handled as a full zone transfer (252)
405
+ // 252 - AXFR - handled as a function call
406
+
407
+ 255 => 'Net_DNS2_RR_ANY',
408
+ 256 => 'Net_DNS2_RR_URI',
409
+ 257 => 'Net_DNS2_RR_CAA',
410
+ 32768 => 'Net_DNS2_RR_TA',
411
+ 32769 => 'Net_DNS2_RR_DLV'
412
+ );
413
+
414
+ /*
415
+ * used to map resource record class names to their id's, and back
416
+ */
417
+ public static $classes_by_id = array();
418
+ public static $classes_by_name = array(
419
+
420
+ 'IN' => self::RR_CLASS_IN, // RFC 1035
421
+ 'CH' => self::RR_CLASS_CH, // RFC 1035
422
+ 'HS' => self::RR_CLASS_HS, // RFC 1035
423
+ 'NONE' => self::RR_CLASS_NONE, // RFC 2136
424
+ 'ANY' => self::RR_CLASS_ANY // RFC 1035
425
+ );
426
+
427
+ /*
428
+ * maps response codes to error messages
429
+ */
430
+ public static $result_code_messages = array(
431
+
432
+ self::RCODE_NOERROR => 'The request completed successfully.',
433
+ self::RCODE_FORMERR => 'The name server was unable to interpret the query.',
434
+ self::RCODE_SERVFAIL => 'The name server was unable to process this query due to a problem with the name server.',
435
+ self::RCODE_NXDOMAIN => 'The domain name referenced in the query does not exist.',
436
+ self::RCODE_NOTIMP => 'The name server does not support the requested kind of query.',
437
+ self::RCODE_REFUSED => 'The name server refuses to perform the specified operation for policy reasons.',
438
+ self::RCODE_YXDOMAIN => 'Name Exists when it should not.',
439
+ self::RCODE_YXRRSET => 'RR Set Exists when it should not.',
440
+ self::RCODE_NXRRSET => 'RR Set that should exist does not.',
441
+ self::RCODE_NOTAUTH => 'Server Not Authoritative for zone.',
442
+ self::RCODE_NOTZONE => 'Name not contained in zone.',
443
+
444
+ self::RCODE_BADSIG => 'TSIG Signature Failure.',
445
+ self::RCODE_BADKEY => 'Key not recognized.',
446
+ self::RCODE_BADTIME => 'Signature out of time window.',
447
+ self::RCODE_BADMODE => 'Bad TKEY Mode.',
448
+ self::RCODE_BADNAME => 'Duplicate key name.',
449
+ self::RCODE_BADALG => 'Algorithm not supported.',
450
+ self::RCODE_BADTRUNC => 'Bad truncation.'
451
+ );
452
+
453
+ /*
454
+ * maps DNS SEC alrorithms to their mnemonics
455
+ */
456
+ public static $algorithm_name_to_id = array();
457
+ public static $algorithm_id_to_name = array(
458
+
459
+ self::DNSSEC_ALGORITHM_RES => 'RES',
460
+ self::DNSSEC_ALGORITHM_RSAMD5 => 'RSAMD5',
461
+ self::DNSSEC_ALGORITHM_DH => 'DH',
462
+ self::DNSSEC_ALGORITHM_DSA => 'DSA',
463
+ self::DNSSEC_ALGORITHM_ECC => 'ECC',
464
+ self::DNSSEC_ALGORITHM_RSASHA1 => 'RSASHA1',
465
+ self::DNSSEC_ALGORITHM_DSANSEC3SHA1 => 'DSA-NSEC3-SHA1',
466
+ self::DSNSEC_ALGORITHM_RSASHA1NSEC3SHA1 => 'RSASHA1-NSEC3-SHA1',
467
+ self::DNSSEC_ALGORITHM_RSASHA256 => 'RSASHA256',
468
+ self::DNSSEC_ALGORITHM_RSASHA512 => 'RSASHA512',
469
+ self::DNSSEC_ALGORITHM_ECCGOST => 'ECC-GOST',
470
+ self::DNSSEC_ALGORITHM_INDIRECT => 'INDIRECT',
471
+ self::DNSSEC_ALGORITHM_PRIVATEDNS => 'PRIVATEDNS',
472
+ self::DNSSEC_ALGORITHM_PRIVATEOID => 'PRIVATEOID'
473
+ );
474
+
475
+ /*
476
+ * maps DNSSEC digest types to their mnemonics
477
+ */
478
+ public static $digest_name_to_id = array();
479
+ public static $digest_id_to_name = array(
480
+
481
+ self::DNSSEC_DIGEST_RES => 'RES',
482
+ self::DNSSEC_DIGEST_SHA1 => 'SHA-1'
483
+ );
484
+
485
+ /*
486
+ * Protocols names - RFC 1010
487
+ */
488
+ public static $protocol_by_id = array();
489
+ public static $protocol_by_name = array(
490
+
491
+ 'ICMP' => 1,
492
+ 'IGMP' => 2,
493
+ 'GGP' => 3,
494
+ 'ST' => 5,
495
+ 'TCP' => 6,
496
+ 'UCL' => 7,
497
+ 'EGP' => 8,
498
+ 'IGP' => 9,
499
+ 'BBN-RCC-MON' => 10,
500
+ 'NVP-II' => 11,
501
+ 'PUP' => 12,
502
+ 'ARGUS' => 13,
503
+ 'EMCON' => 14,
504
+ 'XNET' => 15,
505
+ 'CHAOS' => 16,
506
+ 'UDP' => 17,
507
+ 'MUX' => 18,
508
+ 'DCN-MEAS' => 19,
509
+ 'HMP' => 20,
510
+ 'PRM' => 21,
511
+ 'XNS-IDP' => 22,
512
+ 'TRUNK-1' => 23,
513
+ 'TRUNK-2' => 24,
514
+ 'LEAF-1' => 25,
515
+ 'LEAF-2' => 26,
516
+ 'RDP' => 27,
517
+ 'IRTP' => 28,
518
+ 'ISO-TP4' => 29,
519
+ 'NETBLT' => 30,
520
+ 'MFE-NSP' => 31,
521
+ 'MERIT-INP' => 32,
522
+ 'SEP' => 33,
523
+ // 34 - 60 - Unassigned
524
+ // 61 - any host internal protocol
525
+ 'CFTP' => 62,
526
+ // 63 - any local network
527
+ 'SAT-EXPAK' => 64,
528
+ 'MIT-SUBNET' => 65,
529
+ 'RVD' => 66,
530
+ 'IPPC' => 67,
531
+ // 68 - any distributed file system
532
+ 'SAT-MON' => 69,
533
+ // 70 - Unassigned
534
+ 'IPCV' => 71,
535
+ // 72 - 75 - Unassigned
536
+ 'BR-SAT-MON' => 76,
537
+ // 77 - Unassigned
538
+ 'WB-MON' => 78,
539
+ 'WB-EXPAK' => 79
540
+ // 80 - 254 - Unassigned
541
+ // 255 - Reserved
542
+ );
543
+ }
544
+
545
+ /*
546
+ * Local variables:
547
+ * tab-width: 4
548
+ * c-basic-offset: 4
549
+ * c-hanging-comment-ender-p: nil
550
+ * End:
551
+ */
552
+ ?>
includes/Net/DNS2/Packet.php ADDED
@@ -0,0 +1,449 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ * This file contains code based off the Net::DNS Perl module by
51
+ * Michael Fuhr.
52
+ *
53
+ * This is the copyright notice from the PERL Net::DNS module:
54
+ *
55
+ * Copyright (c) 1997-2000 Michael Fuhr. All rights reserved. This
56
+ * program is free software; you can redistribute it and/or modify it
57
+ * under the same terms as Perl itself.
58
+ *
59
+ */
60
+
61
+ /**
62
+ * This is the base class that holds a standard DNS packet.
63
+ *
64
+ * The Net_DNS2_Packet_Request and Net_DNS2_Packet_Response classes extend this
65
+ * class.
66
+ *
67
+ * @category Networking
68
+ * @package Net_DNS2
69
+ * @author Mike Pultz <mike@mikepultz.com>
70
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
71
+ * @link http://pear.php.net/package/Net_DNS2
72
+ * @see Net_DNS2_Packet_Request, Net_DNS2_Packet_Response
73
+ *
74
+ */
75
+ class Net_DNS2_Packet
76
+ {
77
+ /*
78
+ * the full binary data and length for this packet
79
+ */
80
+ public $rdata;
81
+ public $rdlength;
82
+
83
+ /*
84
+ * the offset pointer used when building/parsing packets
85
+ */
86
+ public $offset = 0;
87
+
88
+ /*
89
+ * Net_DNS2_Header object with the DNS packet header
90
+ */
91
+ public $header;
92
+
93
+ /*
94
+ * array of Net_DNS2_Question objects
95
+ *
96
+ * used as "zone" for updates per RFC2136
97
+ *
98
+ */
99
+ public $question = array();
100
+
101
+ /*
102
+ * array of Net_DNS2_RR Objects for Answers
103
+ *
104
+ * used as "prerequisite" for updates per RFC2136
105
+ *
106
+ */
107
+ public $answer = array();
108
+
109
+ /*
110
+ * array of Net_DNS2_RR Objects for Authority
111
+ *
112
+ * used as "update" for updates per RFC2136
113
+ *
114
+ */
115
+ public $authority = array();
116
+
117
+ /*
118
+ * array of Net_DNS2_RR Objects for Addtitional
119
+ */
120
+ public $additional = array();
121
+
122
+ /*
123
+ * array of compressed labeles
124
+ */
125
+ private $_compressed = array();
126
+
127
+ /**
128
+ * magic __toString() method to return the Net_DNS2_Packet as a string
129
+ *
130
+ * @return string
131
+ * @access public
132
+ *
133
+ */
134
+ public function __toString()
135
+ {
136
+ $output = $this->header->__toString();
137
+
138
+ foreach ($this->question as $x) {
139
+
140
+ $output .= $x->__toString() . "\n";
141
+ }
142
+ foreach ($this->answer as $x) {
143
+
144
+ $output .= $x->__toString() . "\n";
145
+ }
146
+ foreach ($this->authority as $x) {
147
+
148
+ $output .= $x->__toString() . "\n";
149
+ }
150
+ foreach ($this->additional as $x) {
151
+
152
+ $output .= $x->__toString() . "\n";
153
+ }
154
+
155
+ return $output;
156
+ }
157
+
158
+ /**
159
+ * returns a full binary DNS packet
160
+ *
161
+ * @return string
162
+ * @throws Net_DNS2_Exception
163
+ * @access public
164
+ *
165
+ */
166
+ public function get()
167
+ {
168
+ $data = $this->header->get($this);
169
+
170
+ foreach ($this->question as $x) {
171
+
172
+ $data .= $x->get($this);
173
+ }
174
+ foreach ($this->answer as $x) {
175
+
176
+ $data .= $x->get($this);
177
+ }
178
+ foreach ($this->authority as $x) {
179
+
180
+ $data .= $x->get($this);
181
+ }
182
+ foreach ($this->additional as $x) {
183
+
184
+ $data .= $x->get($this);
185
+ }
186
+
187
+ return $data;
188
+ }
189
+
190
+ /**
191
+ * applies a standard DNS name compression on the given name/offset
192
+ *
193
+ * This logic was based on the Net::DNS::Packet::dn_comp() function
194
+ * by Michanel Fuhr
195
+ *
196
+ * @param string $name the name to be compressed
197
+ * @param integer &$offset the offset into the given packet object
198
+ *
199
+ * @return string
200
+ * @access public
201
+ *
202
+ */
203
+ public function compress($name, &$offset)
204
+ {
205
+ $names = explode('.', $name);
206
+ $compname = '';
207
+
208
+ while (!empty($names)) {
209
+
210
+ $dname = join('.', $names);
211
+
212
+ if (isset($this->_compressed[$dname])) {
213
+
214
+ $compname .= pack('n', 0xc000 | $this->_compressed[$dname]);
215
+ $offset += 2;
216
+
217
+ break;
218
+ }
219
+
220
+ $this->_compressed[$dname] = $offset;
221
+ $first = array_shift($names);
222
+
223
+ $length = strlen($first);
224
+ if ($length <= 0) {
225
+ continue;
226
+ }
227
+
228
+ //
229
+ // truncate see RFC1035 2.3.1
230
+ //
231
+ if ($length > 63) {
232
+
233
+ $length = 63;
234
+ $first = substr($first, 0, $length);
235
+ }
236
+
237
+ $compname .= pack('Ca*', $length, $first);
238
+ $offset += $length + 1;
239
+ }
240
+
241
+ if (empty($names)) {
242
+
243
+ $compname .= pack('C', 0);
244
+ $offset++;
245
+ }
246
+
247
+ return $compname;
248
+ }
249
+
250
+ /**
251
+ * applies a standard DNS name compression on the given name/offset
252
+ *
253
+ * This logic was based on the Net::DNS::Packet::dn_comp() function
254
+ * by Michanel Fuhr
255
+ *
256
+ * @param string $name the name to be compressed
257
+ *
258
+ * @return string
259
+ * @access public
260
+ *
261
+ */
262
+ public static function pack($name)
263
+ {
264
+ $offset = 0;
265
+ $names = explode('.', $name);
266
+ $compname = '';
267
+
268
+ while (!empty($names)) {
269
+
270
+ $first = array_shift($names);
271
+ $length = strlen($first);
272
+
273
+ $compname .= pack('Ca*', $length, $first);
274
+ $offset += $length + 1;
275
+ }
276
+
277
+ $compname .= "\0";
278
+ $offset++;
279
+
280
+ return $compname;
281
+ }
282
+
283
+ /**
284
+ * expands the domain name stored at a given offset in a DNS Packet
285
+ *
286
+ * This logic was based on the Net::DNS::Packet::dn_expand() function
287
+ * by Michanel Fuhr
288
+ *
289
+ * @param Net_DNS2_Packet &$packet the DNS packet to look in for the domain name
290
+ * @param integer &$offset the offset into the given packet object
291
+ *
292
+ * @return mixed either the domain name or null if it's not found.
293
+ * @access public
294
+ *
295
+ */
296
+ public static function expand(Net_DNS2_Packet &$packet, &$offset)
297
+ {
298
+ $name = '';
299
+
300
+ while (1) {
301
+ if ($packet->rdlength < ($offset + 1)) {
302
+ return null;
303
+ }
304
+
305
+ $xlen = ord($packet->rdata[$offset]);
306
+ if ($xlen == 0) {
307
+
308
+ ++$offset;
309
+ break;
310
+
311
+ } else if (($xlen & 0xc0) == 0xc0) {
312
+ if ($packet->rdlength < ($offset + 2)) {
313
+
314
+ return null;
315
+ }
316
+
317
+ $ptr = ord($packet->rdata[$offset]) << 8 |
318
+ ord($packet->rdata[$offset+1]);
319
+ $ptr = $ptr & 0x3fff;
320
+
321
+ $name2 = Net_DNS2_Packet::expand($packet, $ptr);
322
+ if (is_null($name2)) {
323
+
324
+ return null;
325
+ }
326
+
327
+ $name .= $name2;
328
+ $offset += 2;
329
+
330
+ break;
331
+ } else {
332
+ ++$offset;
333
+
334
+ if ($packet->rdlength < ($offset + $xlen)) {
335
+
336
+ return null;
337
+ }
338
+
339
+ $elem = '';
340
+ $elem = substr($packet->rdata, $offset, $xlen);
341
+ $name .= $elem . '.';
342
+ $offset += $xlen;
343
+ }
344
+ }
345
+
346
+ return trim($name, '.');
347
+ }
348
+
349
+ /**
350
+ * parses a domain label from a DNS Packet at the given offset
351
+ *
352
+ * @param Net_DNS2_Packet &$packet the DNS packet to look in for the domain name
353
+ * @param integer &$offset the offset into the given packet object
354
+ *
355
+ * @return mixed either the domain name or null if it's not found.
356
+ * @access public
357
+ *
358
+ */
359
+ public static function label(Net_DNS2_Packet &$packet, &$offset)
360
+ {
361
+ $name = '';
362
+
363
+ if ($packet->rdlength < ($offset + 1)) {
364
+
365
+ return null;
366
+ }
367
+
368
+ $xlen = ord($packet->rdata[$offset]);
369
+ ++$offset;
370
+
371
+ if (($xlen + $offset) > $packet->rdlength) {
372
+
373
+ $name = substr($packet->rdata, $offset);
374
+ $offset = $packet->rdlength;
375
+ } else {
376
+
377
+ $name = substr($packet->rdata, $offset, $xlen);
378
+ $offset += $xlen;
379
+ }
380
+
381
+ return $name;
382
+ }
383
+
384
+ /**
385
+ * copies the contents of the given packet, to the local packet object. this
386
+ * function intentionally ignores some of the packet data.
387
+ *
388
+ * @param Net_DNS2_Packet $packet the DNS packet to copy the data from
389
+ *
390
+ * @return boolean
391
+ * @access public
392
+ *
393
+ */
394
+ public function copy(Net_DNS2_Packet $packet)
395
+ {
396
+ $this->header = $packet->header;
397
+ $this->question = $packet->question;
398
+ $this->answer = $packet->answer;
399
+ $this->authority = $packet->authority;
400
+ $this->additional = $packet->additional;
401
+
402
+ return true;
403
+ }
404
+
405
+ /**
406
+ * resets the values in the current packet object
407
+ *
408
+ * @return boolean
409
+ * @access public
410
+ *
411
+ */
412
+ public function reset()
413
+ {
414
+ $this->header->id = $this->header->nextPacketId();
415
+ $this->rdata = '';
416
+ $this->rdlength = 0;
417
+ $this->offset = 0;
418
+ $this->answer = array();
419
+ $this->authority = array();
420
+ $this->additional = array();
421
+ $this->_compressed = array();
422
+
423
+ return true;
424
+ }
425
+
426
+ /**
427
+ * formats an IPv6 IP address in the preferred format
428
+ *
429
+ * @param string $address The IPv6 IP address to format
430
+ *
431
+ * @return string The IPv6 IP address formatted in the new format
432
+ * @access public
433
+ * @deprecated function deprecated in 1.1.3
434
+ *
435
+ */
436
+ public static function formatIPv6($address)
437
+ {
438
+ return Net_DNS2::expandIPv6($address);
439
+ }
440
+ }
441
+
442
+ /*
443
+ * Local variables:
444
+ * tab-width: 4
445
+ * c-basic-offset: 4
446
+ * c-hanging-comment-ender-p: nil
447
+ * End:
448
+ */
449
+ ?>
includes/Net/DNS2/Packet/Request.php ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+
53
+ /**
54
+ * This class handles building new DNS request packets; packets used for DNS
55
+ * queries and updates.
56
+ *
57
+ * @category Networking
58
+ * @package Net_DNS2
59
+ * @author Mike Pultz <mike@mikepultz.com>
60
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
61
+ * @link http://pear.php.net/package/Net_DNS2
62
+ * @see Net_DNS2_Packet
63
+ *
64
+ */
65
+ class Net_DNS2_Packet_Request extends Net_DNS2_Packet
66
+ {
67
+ /**
68
+ * Constructor - builds a new Net_DNS2_Packet_Request object
69
+ *
70
+ * @param string $name the domain name for the packet
71
+ * @param string $type the DNS RR type for the packet
72
+ * @param string $class the DNS class for the packet
73
+ *
74
+ * @throws Net_DNS2_Exception
75
+ * @access public
76
+ *
77
+ */
78
+ public function __construct($name, $type = null, $class = null)
79
+ {
80
+ $this->set($name, $type, $class);
81
+ }
82
+
83
+ /**
84
+ * builds a new Net_DNS2_Packet_Request object
85
+ *
86
+ * @param string $name the domain name for the packet
87
+ * @param string $type the DNS RR type for the packet
88
+ * @param string $class the DNS class for the packet
89
+ *
90
+ * @return boolean
91
+ * @throws Net_DNS2_Exception
92
+ * @access public
93
+ *
94
+ */
95
+ public function set($name, $type = 'A', $class = 'IN')
96
+ {
97
+ //
98
+ // generate a new header
99
+ //
100
+ $this->header = new Net_DNS2_Header;
101
+
102
+ //
103
+ // add a new question
104
+ //
105
+ $q = new Net_DNS2_Question();
106
+
107
+ //
108
+ // allow queries directly to . for the root name servers
109
+ //
110
+ if ($name != '.') {
111
+ $name = trim(strtolower($name), " \t\n\r\0\x0B.");
112
+ }
113
+
114
+ $type = strtoupper(trim($type));
115
+ $class = strtoupper(trim($class));
116
+
117
+ //
118
+ // check that the input string has some data in it
119
+ //
120
+ if (empty($name)) {
121
+
122
+ throw new Net_DNS2_Exception(
123
+ 'empty query string provided',
124
+ Net_DNS2_Lookups::E_PACKET_INVALID
125
+ );
126
+ }
127
+
128
+ //
129
+ // if the type is "*", rename it to "ANY"- both are acceptable.
130
+ //
131
+ if ($type == '*') {
132
+
133
+ $type = 'ANY';
134
+ }
135
+
136
+ //
137
+ // check that the type and class are valid
138
+ //
139
+ if ( (!isset(Net_DNS2_Lookups::$rr_types_by_name[$type]))
140
+ || (!isset(Net_DNS2_Lookups::$classes_by_name[$class]))
141
+ ) {
142
+ throw new Net_DNS2_Exception(
143
+ 'invalid type (' . $type . ') or class (' . $class . ') specified.',
144
+ Net_DNS2_Lookups::E_PACKET_INVALID
145
+ );
146
+ }
147
+
148
+ if ($type == 'PTR') {
149
+
150
+ //
151
+ // if it's a PTR request for an IP address, then make sure we tack on
152
+ // the arpa domain.
153
+ //
154
+ // there are other types of PTR requests, so if an IP adress doesn't match,
155
+ // then just let it flow through and assume it's a hostname
156
+ //
157
+ if (Net_DNS2::isIPv4($name) == true) {
158
+
159
+ //
160
+ // IPv4
161
+ //
162
+ $name = implode('.', array_reverse(explode('.', $name)));
163
+ $name .= '.in-addr.arpa';
164
+
165
+ } else if (Net_DNS2::isIPv6($name) == true) {
166
+
167
+ //
168
+ // IPv6
169
+ //
170
+ $e = Net_DNS2::expandIPv6($name);
171
+ if ($e !== false) {
172
+
173
+ $name = implode(
174
+ '.', array_reverse(str_split(str_replace(':', '', $e)))
175
+ );
176
+
177
+ $name .= '.ip6.arpa';
178
+
179
+ } else {
180
+
181
+ throw new Net_DNS2_Exception(
182
+ 'unsupported PTR value: ' . $name,
183
+ Net_DNS2_Lookups::E_PACKET_INVALID
184
+ );
185
+ }
186
+ }
187
+ }
188
+
189
+ //
190
+ // store the data
191
+ //
192
+ $q->qname = $name;
193
+ $q->qtype = $type;
194
+ $q->qclass = $class;
195
+
196
+ $this->question[] = $q;
197
+
198
+ //
199
+ // the answer, authority and additional are empty; they can be modified
200
+ // after the request is created for UPDATE requests if needed.
201
+ //
202
+ $this->answer = array();
203
+ $this->authority = array();
204
+ $this->additional = array();
205
+
206
+ return true;
207
+ }
208
+ }
209
+
210
+ /*
211
+ * Local variables:
212
+ * tab-width: 4
213
+ * c-basic-offset: 4
214
+ * c-hanging-comment-ender-p: nil
215
+ * End:
216
+ */
217
+ ?>
includes/Net/DNS2/Packet/Response.php ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+
53
+ /**
54
+ * This class handles building new DNS response packets; it parses binary packed
55
+ * packets that come off the wire
56
+ *
57
+ * @category Networking
58
+ * @package Net_DNS2
59
+ * @author Mike Pultz <mike@mikepultz.com>
60
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
61
+ * @link http://pear.php.net/package/Net_DNS2
62
+ * @see Net_DNS2_Packet
63
+ *
64
+ */
65
+ class Net_DNS2_Packet_Response extends Net_DNS2_Packet
66
+ {
67
+ /*
68
+ * The name servers that this response came from
69
+ */
70
+ public $answer_from;
71
+
72
+ /*
73
+ * The socket type the answer came from (TCP/UDP)
74
+ */
75
+ public $answer_socket_type;
76
+
77
+ /*
78
+ * The query response time in microseconds
79
+ */
80
+ public $response_time = 0;
81
+
82
+ /**
83
+ * Constructor - builds a new Net_DNS2_Packet_Response object
84
+ *
85
+ * @param string $data binary DNS packet
86
+ * @param integer $size the length of the DNS packet
87
+ *
88
+ * @throws Net_DNS2_Exception
89
+ * @access public
90
+ *
91
+ */
92
+ public function __construct($data, $size)
93
+ {
94
+ $this->set($data, $size);
95
+ }
96
+
97
+ /**
98
+ * builds a new Net_DNS2_Packet_Response object
99
+ *
100
+ * @param string $data binary DNS packet
101
+ * @param integer $size the length of the DNS packet
102
+ *
103
+ * @return boolean
104
+ * @throws Net_DNS2_Exception
105
+ * @access public
106
+ *
107
+ */
108
+ public function set($data, $size)
109
+ {
110
+ //
111
+ // store the full packet
112
+ //
113
+ $this->rdata = $data;
114
+ $this->rdlength = $size;
115
+
116
+ //
117
+ // parse the header
118
+ //
119
+ // we don't bother checking the size earlier, because the first thing the
120
+ // header class does, is check the size and throw and exception if it's
121
+ // invalid.
122
+ //
123
+ $this->header = new Net_DNS2_Header($this);
124
+
125
+ //
126
+ // if the truncation bit is set, then just return right here, because the
127
+ // rest of the packet is probably empty; and there's no point in processing
128
+ // anything else.
129
+ //
130
+ // we also don't need to worry about checking to see if the the header is
131
+ // null or not, since the Net_DNS2_Header() constructor will throw an
132
+ // exception if the packet is invalid.
133
+ //
134
+ if ($this->header->tc == 1) {
135
+
136
+ return false;
137
+ }
138
+
139
+ //
140
+ // parse the questions
141
+ //
142
+ for ($x = 0; $x < $this->header->qdcount; ++$x) {
143
+
144
+ $this->question[$x] = new Net_DNS2_Question($this);
145
+ }
146
+
147
+ //
148
+ // parse the answers
149
+ //
150
+ for ($x = 0; $x < $this->header->ancount; ++$x) {
151
+
152
+ $o = Net_DNS2_RR::parse($this);
153
+ if (!is_null($o)) {
154
+
155
+ $this->answer[] = $o;
156
+ }
157
+ }
158
+
159
+ //
160
+ // parse the authority section
161
+ //
162
+ for ($x = 0; $x < $this->header->nscount; ++$x) {
163
+
164
+ $o = Net_DNS2_RR::parse($this);
165
+ if (!is_null($o)) {
166
+
167
+ $this->authority[] = $o;
168
+ }
169
+ }
170
+
171
+ //
172
+ // parse the additional section
173
+ //
174
+ for ($x = 0; $x < $this->header->arcount; ++$x) {
175
+
176
+ $o = Net_DNS2_RR::parse($this);
177
+ if (!is_null($o)) {
178
+
179
+ $this->additional[] = $o;
180
+ }
181
+ }
182
+
183
+ return true;
184
+ }
185
+ }
186
+
187
+ /*
188
+ * Local variables:
189
+ * tab-width: 4
190
+ * c-basic-offset: 4
191
+ * c-hanging-comment-ender-p: nil
192
+ * End:
193
+ */
194
+ ?>
includes/Net/DNS2/PrivateKey.php ADDED
@@ -0,0 +1,424 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2011 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.1.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * SSL Private Key container class
54
+ *
55
+ * @category Networking
56
+ * @package Net_DNS2
57
+ * @author Mike Pultz <mike@mikepultz.com>
58
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
59
+ * @link http://pear.php.net/package/Net_DNS2
60
+ *
61
+ */
62
+ class Net_DNS2_PrivateKey
63
+ {
64
+ /*
65
+ * the filename that was loaded; stored for reference
66
+ */
67
+ public $filename;
68
+
69
+ /*
70
+ * the keytag for the signature
71
+ */
72
+ public $keytag;
73
+
74
+ /*
75
+ * the sign name for the signature
76
+ */
77
+ public $signname;
78
+
79
+ /*
80
+ * the algorithm used for the signature
81
+ */
82
+ public $algorithm;
83
+
84
+ /*
85
+ * the key format fo the signature
86
+ */
87
+ public $key_format;
88
+
89
+ /*
90
+ * the openssl private key id
91
+ */
92
+ public $instance;
93
+
94
+ /*
95
+ * RSA: modulus
96
+ */
97
+ private $_modulus;
98
+
99
+ /*
100
+ * RSA: public exponent
101
+ */
102
+ private $_public_exponent;
103
+
104
+ /*
105
+ * RSA: rivate exponent
106
+ */
107
+ private $_private_exponent;
108
+
109
+ /*
110
+ * RSA: prime1
111
+ */
112
+ private $_prime1;
113
+
114
+ /*
115
+ * RSA: prime2
116
+ */
117
+ private $_prime2;
118
+
119
+ /*
120
+ * RSA: exponent 1
121
+ */
122
+ private $_exponent1;
123
+
124
+ /*
125
+ * RSA: exponent 2
126
+ */
127
+ private $_exponent2;
128
+
129
+ /*
130
+ * RSA: coefficient
131
+ */
132
+ private $_coefficient;
133
+
134
+ /*
135
+ * DSA: prime
136
+ */
137
+ public $prime;
138
+
139
+ /*
140
+ * DSA: subprime
141
+ */
142
+ public $subprime;
143
+
144
+ /*
145
+ * DSA: base
146
+ */
147
+ public $base;
148
+
149
+ /*
150
+ * DSA: private value
151
+ */
152
+ public $private_value;
153
+
154
+ /*
155
+ * DSA: public value
156
+ */
157
+ public $public_value;
158
+
159
+ /**
160
+ * Constructor - base constructor the private key container class
161
+ *
162
+ * @param string $file path to a private-key file to parse and load
163
+ *
164
+ * @throws Net_DNS2_Exception
165
+ * @access public
166
+ *
167
+ */
168
+ public function __construct($file = null)
169
+ {
170
+ if (isset($file)) {
171
+ $this->parseFile($file);
172
+ }
173
+ }
174
+
175
+ /**
176
+ * parses a private key file generated by dnssec-keygen
177
+ *
178
+ * @param string $file path to a private-key file to parse and load
179
+ *
180
+ * @return boolean
181
+ * @throws Net_DNS2_Exception
182
+ * @access public
183
+ *
184
+ */
185
+ public function parseFile($file)
186
+ {
187
+ //
188
+ // check for OpenSSL
189
+ //
190
+ if (extension_loaded('openssl') === false) {
191
+
192
+ throw new Net_DNS2_Exception(
193
+ 'the OpenSSL extension is required to use parse private key.',
194
+ Net_DNS2_Lookups::E_OPENSSL_UNAVAIL
195
+ );
196
+ }
197
+
198
+ //
199
+ // check to make sure the file exists
200
+ //
201
+ if (is_readable($file) == false) {
202
+
203
+ throw new Net_DNS2_Exception(
204
+ 'invalid private key file: ' . $file,
205
+ Net_DNS2_Lookups::E_OPENSSL_INV_PKEY
206
+ );
207
+ }
208
+
209
+ //
210
+ // get the base filename, and parse it for the local value
211
+ //
212
+ $keyname = basename($file);
213
+ if (strlen($keyname) == 0) {
214
+
215
+ throw new Net_DNS2_Exception(
216
+ 'failed to get basename() for: ' . $file,
217
+ Net_DNS2_Lookups::E_OPENSSL_INV_PKEY
218
+ );
219
+ }
220
+
221
+ //
222
+ // parse the keyname
223
+ //
224
+ if (preg_match("/K(.*)\.\+(\d{3})\+(\d*)\.private/", $keyname, $matches)) {
225
+
226
+ $this->signname = $matches[1];
227
+ $this->algorithm = intval($matches[2]);
228
+ $this->keytag = intval($matches[3]);
229
+
230
+ } else {
231
+
232
+ throw new Net_DNS2_Exception(
233
+ 'file ' . $keyname . ' does not look like a private key file!',
234
+ Net_DNS2_Lookups::E_OPENSSL_INV_PKEY
235
+ );
236
+ }
237
+
238
+ //
239
+ // read all the data from the
240
+ //
241
+ $data = file($file, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);
242
+ if (count($data) == 0) {
243
+
244
+ throw new Net_DNS2_Exception(
245
+ 'file ' . $keyname . ' is empty!',
246
+ Net_DNS2_Lookups::E_OPENSSL_INV_PKEY
247
+ );
248
+ }
249
+
250
+ foreach ($data as $line) {
251
+
252
+ list($key, $value) = explode(':', $line);
253
+
254
+ $key = trim($key);
255
+ $value = trim($value);
256
+
257
+ switch(strtolower($key)) {
258
+
259
+ case 'private-key-format':
260
+ $this->_key_format = $value;
261
+ break;
262
+
263
+ case 'algorithm':
264
+ if ($this->algorithm != $value) {
265
+ throw new Net_DNS2_Exception(
266
+ 'Algorithm mis-match! filename is ' . $this->algorithm .
267
+ ', contents say ' . $value,
268
+ Net_DNS2_Lookups::E_OPENSSL_INV_ALGO
269
+ );
270
+ }
271
+ break;
272
+
273
+ //
274
+ // RSA
275
+ //
276
+ case 'modulus':
277
+ $this->_modulus = $value;
278
+ break;
279
+
280
+ case 'publicexponent':
281
+ $this->_public_exponent = $value;
282
+ break;
283
+
284
+ case 'privateexponent':
285
+ $this->_private_exponent = $value;
286
+ break;
287
+
288
+ case 'prime1':
289
+ $this->_prime1 = $value;
290
+ break;
291
+
292
+ case 'prime2':
293
+ $this->_prime2 = $value;
294
+ break;
295
+
296
+ case 'exponent1':
297
+ $this->_exponent1 = $value;
298
+ break;
299
+
300
+ case 'exponent2':
301
+ $this->_exponent2 = $value;
302
+ break;
303
+
304
+ case 'coefficient':
305
+ $this->_coefficient = $value;
306
+ break;
307
+
308
+ //
309
+ // DSA - this won't work in PHP until the OpenSSL extension is better
310
+ //
311
+ case 'prime(p)':
312
+ $this->prime = $value;
313
+ break;
314
+
315
+ case 'subprime(q)':
316
+ $this->subprime = $value;
317
+ break;
318
+
319
+ case 'base(g)':
320
+ $this->base = $value;
321
+ break;
322
+
323
+ case 'private_value(x)':
324
+ $this->private_value = $value;
325
+ break;
326
+
327
+ case 'public_value(y)':
328
+ $this->public_value = $value;
329
+ break;
330
+
331
+ default:
332
+ throw new Net_DNS2_Exception(
333
+ 'unknown private key data: ' . $key . ': ' . $value,
334
+ Net_DNS2_Lookups::E_OPENSSL_INV_PKEY
335
+ );
336
+ }
337
+ }
338
+
339
+ //
340
+ // generate the private key
341
+ //
342
+ $args = array();
343
+
344
+ switch($this->algorithm) {
345
+
346
+ //
347
+ // RSA
348
+ //
349
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSAMD5:
350
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA1:
351
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA256:
352
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA512:
353
+
354
+ $args = array(
355
+
356
+ 'rsa' => array(
357
+
358
+ 'n' => base64_decode($this->_modulus),
359
+ 'e' => base64_decode($this->_public_exponent),
360
+ 'd' => base64_decode($this->_private_exponent),
361
+ 'p' => base64_decode($this->_prime1),
362
+ 'q' => base64_decode($this->_prime2),
363
+ 'dmp1' => base64_decode($this->_exponent1),
364
+ 'dmq1' => base64_decode($this->_exponent2),
365
+ 'iqmp' => base64_decode($this->_coefficient)
366
+ )
367
+ );
368
+
369
+ break;
370
+
371
+ //
372
+ // DSA - this won't work in PHP until the OpenSSL extension is better
373
+ //
374
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_DSA:
375
+
376
+ $args = array(
377
+
378
+ 'dsa' => array(
379
+
380
+ 'p' => base64_decode($this->prime),
381
+ 'q' => base64_decode($this->subprime),
382
+ 'g' => base64_decode($this->base),
383
+ 'priv_key' => base64_decode($this->private_value),
384
+ 'pub_key' => base64_decode($this->public_value)
385
+ )
386
+ );
387
+
388
+ break;
389
+
390
+ default:
391
+ throw new Net_DNS2_Exception(
392
+ 'we only currently support RSAMD5 and RSASHA1 encryption.',
393
+ Net_DNS2_Lookups::E_OPENSSL_INV_PKEY
394
+ );
395
+ }
396
+
397
+ //
398
+ // generate and store the key
399
+ //
400
+ $this->instance = openssl_pkey_new($args);
401
+ if ($this->instance === false) {
402
+ throw new Net_DNS2_Exception(
403
+ openssl_error_string(),
404
+ Net_DNS2_Lookups::E_OPENSSL_ERROR
405
+ );
406
+ }
407
+
408
+ //
409
+ // store the filename incase we need it for something
410
+ //
411
+ $this->filename = $file;
412
+
413
+ return true;
414
+ }
415
+ }
416
+
417
+ /*
418
+ * Local variables:
419
+ * tab-width: 4
420
+ * c-basic-offset: 4
421
+ * c-hanging-comment-ender-p: nil
422
+ * End:
423
+ */
424
+ ?>
includes/Net/DNS2/Question.php ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * This class handles parsing and constructing the question sectino of DNS
54
+ * packets.
55
+ *
56
+ * This is referred to as the "zone" for update per RFC2136
57
+ *
58
+ * DNS question format - RFC1035 section 4.1.2
59
+ *
60
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
61
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
62
+ * | |
63
+ * / QNAME /
64
+ * / /
65
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
66
+ * | QTYPE |
67
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
68
+ * | QCLASS |
69
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
70
+ *
71
+ * @category Networking
72
+ * @package Net_DNS2
73
+ * @author Mike Pultz <mike@mikepultz.com>
74
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
75
+ * @link http://pear.php.net/package/Net_DNS2
76
+ * @see Net_DNS2_Packet
77
+ *
78
+ */
79
+ class Net_DNS2_Question
80
+ {
81
+ /*
82
+ * The name of the question
83
+ *
84
+ * referred to as "zname" for updates per RFC2136
85
+ *
86
+ */
87
+ public $qname;
88
+
89
+ /*
90
+ * The RR type for the questino
91
+ *
92
+ * referred to as "ztype" for updates per RFC2136
93
+ *
94
+ */
95
+ public $qtype;
96
+
97
+ /*
98
+ * The RR class for the questino
99
+ *
100
+ * referred to as "zclass" for updates per RFC2136
101
+ *
102
+ */
103
+ public $qclass;
104
+
105
+ /**
106
+ * Constructor - builds a new Net_DNS2_Question object
107
+ *
108
+ * @param mixed &$packet either a Net_DNS2_Packet object, or null to
109
+ * build an empty object
110
+ *
111
+ * @throws Net_DNS2_Exception
112
+ * @access public
113
+ *
114
+ */
115
+ public function __construct(Net_DNS2_Packet &$packet = null)
116
+ {
117
+ if (!is_null($packet)) {
118
+
119
+ $this->set($packet);
120
+ } else {
121
+
122
+ $this->qname = '';
123
+ $this->qtype = 'A';
124
+ $this->qclass = 'IN';
125
+ }
126
+ }
127
+
128
+ /**
129
+ * magic __toString() function to return the Net_DNS2_Question object as a string
130
+ *
131
+ * @return string
132
+ * @access public
133
+ *
134
+ */
135
+ public function __toString()
136
+ {
137
+ return ";;\n;; Question:\n;;\t " . $this->qname . '. ' .
138
+ $this->qtype . ' ' . $this->qclass . "\n";
139
+ }
140
+
141
+ /**
142
+ * builds a new Net_DNS2_Header object from a Net_DNS2_Packet object
143
+ *
144
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet object
145
+ *
146
+ * @return boolean
147
+ * @throws Net_DNS2_Exception
148
+ * @access public
149
+ *
150
+ */
151
+ public function set(Net_DNS2_Packet &$packet)
152
+ {
153
+ //
154
+ // expand the name
155
+ //
156
+ $this->qname = $packet->expand($packet, $packet->offset);
157
+ if ($packet->rdlength < ($packet->offset + 4)) {
158
+
159
+ throw new Net_DNS2_Exception(
160
+ 'invalid question section: to small',
161
+ Net_DNS2_Lookups::E_QUESTION_INVALID
162
+ );
163
+ }
164
+
165
+ //
166
+ // unpack the type and class
167
+ //
168
+ $type = ord($packet->rdata[$packet->offset++]) << 8 |
169
+ ord($packet->rdata[$packet->offset++]);
170
+ $class = ord($packet->rdata[$packet->offset++]) << 8 |
171
+ ord($packet->rdata[$packet->offset++]);
172
+
173
+ //
174
+ // validate it
175
+ //
176
+ $type_name = Net_DNS2_Lookups::$rr_types_by_id[$type];
177
+ $class_name = Net_DNS2_Lookups::$classes_by_id[$class];
178
+
179
+ if ( (!isset($type_name)) || (!isset($class_name)) ) {
180
+
181
+ throw new Net_DNS2_Exception(
182
+ 'invalid question section: invalid type (' . $type .
183
+ ') or class (' . $class . ') specified.',
184
+ Net_DNS2_Lookups::E_QUESTION_INVALID
185
+ );
186
+ }
187
+
188
+ //
189
+ // store it
190
+ //
191
+ $this->qtype = $type_name;
192
+ $this->qclass = $class_name;
193
+
194
+ return true;
195
+ }
196
+
197
+ /**
198
+ * returns a binary packed Net_DNS2_Question object
199
+ *
200
+ * @param Net_DNS2_Packet &$packet the Net_DNS2_Packet object this question is
201
+ * part of. This needs to be passed in so that
202
+ * the compressed qname value can be packed in
203
+ * with the names of the other parts of the
204
+ * packet.
205
+ *
206
+ * @return string
207
+ * @throws Net_DNS2_Exception
208
+ * @access public
209
+ *
210
+ */
211
+ public function get(Net_DNS2_Packet &$packet)
212
+ {
213
+ //
214
+ // validate the type and class
215
+ //
216
+ $type = Net_DNS2_Lookups::$rr_types_by_name[$this->qtype];
217
+ $class = Net_DNS2_Lookups::$classes_by_name[$this->qclass];
218
+
219
+ if ( (!isset($type)) || (!isset($class)) ) {
220
+
221
+ throw new Net_DNS2_Exception(
222
+ 'invalid question section: invalid type (' . $this->qtype .
223
+ ') or class (' . $this->qclass . ') specified.',
224
+ Net_DNS2_Lookups::E_QUESTION_INVALID
225
+ );
226
+ }
227
+
228
+ $data = $packet->compress($this->qname, $packet->offset);
229
+
230
+ $data .= chr($type << 8) . chr($type) . chr($class << 8) . chr($class);
231
+ $packet->offset += 4;
232
+
233
+ return $data;
234
+ }
235
+ }
236
+
237
+ /*
238
+ * Local variables:
239
+ * tab-width: 4
240
+ * c-basic-offset: 4
241
+ * c-hanging-comment-ender-p: nil
242
+ * End:
243
+ */
244
+ ?>
includes/Net/DNS2/RR.php ADDED
@@ -0,0 +1,641 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+
53
+ /**
54
+ * This is the base class for DNS Resource Records
55
+ *
56
+ * Each resource record type (defined in RR/*.php) extends this class for
57
+ * base functionality.
58
+ *
59
+ * This class handles parsing and constructing the common parts of the DNS
60
+ * resource records, while the RR specific functionality is handled in each
61
+ * child class.
62
+ *
63
+ * DNS resource record format - RFC1035 section 4.1.3
64
+ *
65
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
66
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
67
+ * | |
68
+ * / /
69
+ * / NAME /
70
+ * | |
71
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
72
+ * | TYPE |
73
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
74
+ * | CLASS |
75
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
76
+ * | TTL |
77
+ * | |
78
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
79
+ * | RDLENGTH |
80
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
81
+ * / RDATA /
82
+ * / /
83
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
84
+ *
85
+ * @category Networking
86
+ * @package Net_DNS2
87
+ * @author Mike Pultz <mike@mikepultz.com>
88
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
89
+ * @link http://pear.php.net/package/Net_DNS2
90
+ *
91
+ */
92
+ abstract class Net_DNS2_RR
93
+ {
94
+ /*
95
+ * The name of the resource record
96
+ */
97
+ public $name;
98
+
99
+ /*
100
+ * The resource record type
101
+ */
102
+ public $type;
103
+
104
+ /*
105
+ * The resouce record class
106
+ */
107
+ public $class;
108
+
109
+ /*
110
+ * The time to live for this resource record
111
+ */
112
+ public $ttl;
113
+
114
+ /*
115
+ * The length of the rdata field
116
+ */
117
+ public $rdlength;
118
+
119
+ /*
120
+ * The resource record specific data as a packed binary string
121
+ */
122
+ public $rdata;
123
+
124
+ /**
125
+ * abstract definition - method to return a RR as a string; not to
126
+ * be confused with the __toString() magic method.
127
+ *
128
+ * @return string
129
+ * @access protected
130
+ *
131
+ */
132
+ abstract protected function rrToString();
133
+
134
+ /**
135
+ * abstract definition - parses a RR from a standard DNS config line
136
+ *
137
+ * @param array $rdata a string split line of values for the rdata
138
+ *
139
+ * @return boolean
140
+ * @access protected
141
+ *
142
+ */
143
+ abstract protected function rrFromString(array $rdata);
144
+
145
+ /**
146
+ * abstract definition - sets a Net_DNS2_RR from a Net_DNS2_Packet object
147
+ *
148
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
149
+ *
150
+ * @return boolean
151
+ * @access protected
152
+ *
153
+ */
154
+ abstract protected function rrSet(Net_DNS2_Packet &$packet);
155
+
156
+ /**
157
+ * abstract definition - returns a binary packet DNS RR object
158
+ *
159
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
160
+ * compressed names
161
+ *
162
+ * @return mixed either returns a binary packed string or
163
+ * null on failure
164
+ * @access protected
165
+ *
166
+ */
167
+ abstract protected function rrGet(Net_DNS2_Packet &$packet);
168
+
169
+ /**
170
+ * Constructor - builds a new Net_DNS2_RR object
171
+ *
172
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet or null to create
173
+ * an empty object
174
+ * @param array $rr an array with RR parse values or null to
175
+ * create an empty object
176
+ *
177
+ * @throws Net_DNS2_Exception
178
+ * @access public
179
+ *
180
+ */
181
+ public function __construct(Net_DNS2_Packet &$packet = null, array $rr = null)
182
+ {
183
+ if ( (!is_null($packet)) && (!is_null($rr)) ) {
184
+
185
+ if ($this->set($packet, $rr) == false) {
186
+
187
+ throw new Net_DNS2_Exception(
188
+ 'failed to generate resource record',
189
+ Net_DNS2_Lookups::E_RR_INVALID
190
+ );
191
+ }
192
+ } else {
193
+
194
+ $class = Net_DNS2_Lookups::$rr_types_class_to_id[get_class($this)];
195
+ if (isset($class)) {
196
+
197
+ $this->type = Net_DNS2_Lookups::$rr_types_by_id[$class];
198
+ }
199
+
200
+ $this->class = 'IN';
201
+ $this->ttl = 86400;
202
+ }
203
+ }
204
+
205
+ /**
206
+ * magic __toString() method to return the Net_DNS2_RR object object as a string
207
+ *
208
+ * @return string
209
+ * @access public
210
+ *
211
+ */
212
+ public function __toString()
213
+ {
214
+ return $this->name . '. ' . $this->ttl . ' ' . $this->class .
215
+ ' ' . $this->type . ' ' . $this->rrToString();
216
+ }
217
+
218
+ /**
219
+ * return a formatted string; if a string has spaces in it, then return
220
+ * it with double quotes around it, otherwise, return it as it was passed in.
221
+ *
222
+ * @param string $string the string to format
223
+ *
224
+ * @return string
225
+ * @access protected
226
+ *
227
+ */
228
+ protected function formatString($string)
229
+ {
230
+ return '"' . str_replace('"', '\"', trim($string, '"')) . '"';
231
+ }
232
+
233
+ /**
234
+ * builds an array of strings from an array of chunks of text split by spaces
235
+ *
236
+ * @param array $chunks an array of chunks of text split by spaces
237
+ *
238
+ * @return array
239
+ * @access protected
240
+ *
241
+ */
242
+ protected function buildString(array $chunks)
243
+ {
244
+ $data = array();
245
+ $c = 0;
246
+ $in = false;
247
+
248
+ foreach ($chunks as $r) {
249
+
250
+ $r = trim($r);
251
+ if (strlen($r) == 0) {
252
+ continue;
253
+ }
254
+
255
+ if ( ($r[0] == '"')
256
+ && ($r[strlen($r) - 1] == '"')
257
+ && ($r[strlen($r) - 2] != '\\')
258
+ ) {
259
+
260
+ $data[$c] = $r;
261
+ ++$c;
262
+ $in = false;
263
+
264
+ } else if ($r[0] == '"') {
265
+
266
+ $data[$c] = $r;
267
+ $in = true;
268
+
269
+ } else if ( ($r[strlen($r) - 1] == '"')
270
+ && ($r[strlen($r) - 2] != '\\')
271
+ ) {
272
+
273
+ $data[$c] .= ' ' . $r;
274
+ ++$c;
275
+ $in = false;
276
+
277
+ } else {
278
+
279
+ if ($in == true) {
280
+ $data[$c] .= ' ' . $r;
281
+ } else {
282
+ $data[$c++] = $r;
283
+ }
284
+ }
285
+ }
286
+
287
+ foreach ($data as $index => $string) {
288
+
289
+ $data[$index] = str_replace('\"', '"', trim($string, '"'));
290
+ }
291
+
292
+ return $data;
293
+ }
294
+
295
+ /**
296
+ * builds a new Net_DNS2_RR object
297
+ *
298
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet or null to create
299
+ * an empty object
300
+ * @param array $rr an array with RR parse values or null to
301
+ * create an empty object
302
+ *
303
+ * @return boolean
304
+ * @throws Net_DNS2_Exception
305
+ * @access public
306
+ *
307
+ */
308
+ public function set(Net_DNS2_Packet &$packet, array $rr)
309
+ {
310
+ $this->name = $rr['name'];
311
+ $this->type = Net_DNS2_Lookups::$rr_types_by_id[$rr['type']];
312
+
313
+ //
314
+ // for RR OPT (41), the class value includes the requestors UDP payload size,
315
+ // and not a class value
316
+ //
317
+ if ($this->type == 'OPT') {
318
+ $this->class = $rr['class'];
319
+ } else {
320
+ $this->class = Net_DNS2_Lookups::$classes_by_id[$rr['class']];
321
+ }
322
+
323
+ $this->ttl = $rr['ttl'];
324
+ $this->rdlength = $rr['rdlength'];
325
+ $this->rdata = substr($packet->rdata, $packet->offset, $rr['rdlength']);
326
+
327
+ return $this->rrSet($packet);
328
+ }
329
+
330
+ /**
331
+ * returns a binary packed DNS RR object
332
+ *
333
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet used for
334
+ * compressing names
335
+ *
336
+ * @return string
337
+ * @throws Net_DNS2_Exception
338
+ * @access public
339
+ *
340
+ */
341
+ public function get(Net_DNS2_Packet &$packet)
342
+ {
343
+ $data = '';
344
+ $rdata = '';
345
+
346
+ //
347
+ // pack the name
348
+ //
349
+ $data = $packet->compress($this->name, $packet->offset);
350
+
351
+ //
352
+ // pack the main values
353
+ //
354
+ if ($this->type == 'OPT') {
355
+
356
+ //
357
+ // pre-build the TTL value
358
+ //
359
+ $this->preBuild();
360
+
361
+ //
362
+ // the class value is different for OPT types
363
+ //
364
+ $data .= pack(
365
+ 'nnN',
366
+ Net_DNS2_Lookups::$rr_types_by_name[$this->type],
367
+ $this->class,
368
+ $this->ttl
369
+ );
370
+ } else {
371
+
372
+ $data .= pack(
373
+ 'nnN',
374
+ Net_DNS2_Lookups::$rr_types_by_name[$this->type],
375
+ Net_DNS2_Lookups::$classes_by_name[$this->class],
376
+ $this->ttl
377
+ );
378
+ }
379
+
380
+ //
381
+ // increase the offset, and allow for the rdlength
382
+ //
383
+ $packet->offset += 10;
384
+
385
+ //
386
+ // get the RR specific details
387
+ //
388
+ if ($this->rdlength != -1) {
389
+
390
+ $rdata = $this->rrGet($packet);
391
+ }
392
+
393
+ //
394
+ // add the RR
395
+ //
396
+ $data .= pack('n', strlen($rdata)) . $rdata;
397
+
398
+ return $data;
399
+ }
400
+
401
+ /**
402
+ * parses a binary packet, and returns the appropriate Net_DNS2_RR object,
403
+ * based on the RR type of the binary content.
404
+ *
405
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet used for
406
+ * decompressing names
407
+ *
408
+ * @return mixed returns a new Net_DNS2_RR_* object for
409
+ * the given RR
410
+ * @throws Net_DNS2_Exception
411
+ * @access public
412
+ *
413
+ */
414
+ public static function parse(Net_DNS2_Packet &$packet)
415
+ {
416
+ $object = array();
417
+
418
+ //
419
+ // expand the name
420
+ //
421
+ $object['name'] = $packet->expand($packet, $packet->offset);
422
+ if (is_null($object['name'])) {
423
+
424
+ throw new Net_DNS2_Exception(
425
+ 'failed to parse resource record: failed to expand name.',
426
+ Net_DNS2_Lookups::E_PARSE_ERROR
427
+ );
428
+ }
429
+ if ($packet->rdlength < ($packet->offset + 10)) {
430
+
431
+ throw new Net_DNS2_Exception(
432
+ 'failed to parse resource record: packet too small.',
433
+ Net_DNS2_Lookups::E_PARSE_ERROR
434
+ );
435
+ }
436
+
437
+ //
438
+ // unpack the RR details
439
+ //
440
+ $object['type'] = ord($packet->rdata[$packet->offset++]) << 8 |
441
+ ord($packet->rdata[$packet->offset++]);
442
+ $object['class'] = ord($packet->rdata[$packet->offset++]) << 8 |
443
+ ord($packet->rdata[$packet->offset++]);
444
+
445
+ $object['ttl'] = ord($packet->rdata[$packet->offset++]) << 24 |
446
+ ord($packet->rdata[$packet->offset++]) << 16 |
447
+ ord($packet->rdata[$packet->offset++]) << 8 |
448
+ ord($packet->rdata[$packet->offset++]);
449
+
450
+ $object['rdlength'] = ord($packet->rdata[$packet->offset++]) << 8 |
451
+ ord($packet->rdata[$packet->offset++]);
452
+
453
+ if ($packet->rdlength < ($packet->offset + $object['rdlength'])) {
454
+ return null;
455
+ }
456
+
457
+ //
458
+ // lookup the class to use
459
+ //
460
+ $o = null;
461
+ $class = Net_DNS2_Lookups::$rr_types_id_to_class[$object['type']];
462
+
463
+ if (isset($class)) {
464
+
465
+ $o = new $class($packet, $object);
466
+ if ($o) {
467
+
468
+ $packet->offset += $object['rdlength'];
469
+ }
470
+ } else {
471
+
472
+ throw new Net_DNS2_Exception(
473
+ 'un-implemented resource record type: ' . $object['type'],
474
+ Net_DNS2_Lookups::E_RR_INVALID
475
+ );
476
+ }
477
+
478
+ return $o;
479
+ }
480
+
481
+ /**
482
+ * cleans up some RR data
483
+ *
484
+ * @param string $data the text string to clean
485
+ *
486
+ * @return string returns the cleaned string
487
+ *
488
+ * @access public
489
+ *
490
+ */
491
+ public function cleanString($data)
492
+ {
493
+ return strtolower(rtrim($data, '.'));
494
+ }
495
+
496
+ /**
497
+ * parses a standard RR format lines, as defined by rfc1035 (kinda)
498
+ *
499
+ * In our implementation, the domain *must* be specified- format must be
500
+ *
501
+ * <name> [<ttl>] [<class>] <type> <rdata>
502
+ * or
503
+ * <name> [<class>] [<ttl>] <type> <rdata>
504
+ *
505
+ * name, title, class and type are parsed by this function, rdata is passed
506
+ * to the RR specific classes for parsing.
507
+ *
508
+ * @param string $line a standard DNS config line
509
+ *
510
+ * @return mixed returns a new Net_DNS2_RR_* object for the given RR
511
+ * @throws Net_DNS2_Exception
512
+ * @access public
513
+ *
514
+ */
515
+ public static function fromString($line)
516
+ {
517
+ if (strlen($line) == 0) {
518
+ throw new Net_DNS2_Exception(
519
+ 'empty config line provided.',
520
+ Net_DNS2_Lookups::E_PARSE_ERROR
521
+ );
522
+ }
523
+
524
+ $name = '';
525
+ $type = '';
526
+ $class = 'IN';
527
+ $ttl = 86400;
528
+
529
+ //
530
+ // split the line by spaces
531
+ //
532
+ $values = preg_split('/[\s]+/', $line);
533
+ if (count($values) < 3) {
534
+
535
+ throw new Net_DNS2_Exception(
536
+ 'failed to parse config: minimum of name, type and rdata required.',
537
+ Net_DNS2_Lookups::E_PARSE_ERROR
538
+ );
539
+ }
540
+
541
+ //
542
+ // assume the first value is the name
543
+ //
544
+ $name = trim(strtolower(array_shift($values)), '.');
545
+
546
+ //
547
+ // The next value is either a TTL, Class or Type
548
+ //
549
+ foreach ($values as $value) {
550
+
551
+ switch($value) {
552
+ case is_numeric($value):
553
+
554
+ $ttl = array_shift($values);
555
+ break;
556
+
557
+ //
558
+ // PHP SUCKS!
559
+ //
560
+ case ($value === 0):
561
+ $ttl = array_shift($values);
562
+ break;
563
+
564
+ case isset(Net_DNS2_Lookups::$classes_by_name[strtoupper($value)]):
565
+
566
+ $class = strtoupper(array_shift($values));
567
+ break;
568
+
569
+ case isset(Net_DNS2_Lookups::$rr_types_by_name[strtoupper($value)]):
570
+
571
+ $type = strtoupper(array_shift($values));
572
+ break 2;
573
+ break;
574
+ default:
575
+
576
+ throw new Net_DNS2_Exception(
577
+ 'invalid config line provided: unknown file: ' . $value,
578
+ Net_DNS2_Lookups::E_PARSE_ERROR
579
+ );
580
+ }
581
+ }
582
+
583
+ //
584
+ // lookup the class to use
585
+ //
586
+ $o = null;
587
+ $class_name = Net_DNS2_Lookups::$rr_types_id_to_class[
588
+ Net_DNS2_Lookups::$rr_types_by_name[$type]
589
+ ];
590
+
591
+ if (isset($class_name)) {
592
+
593
+ $o = new $class_name;
594
+ if (!is_null($o)) {
595
+
596
+ //
597
+ // set the parsed values
598
+ //
599
+ $o->name = $name;
600
+ $o->class = $class;
601
+ $o->ttl = $ttl;
602
+
603
+ //
604
+ // parse the rdata
605
+ //
606
+ if ($o->rrFromString($values) === false) {
607
+
608
+ throw new Net_DNS2_Exception(
609
+ 'failed to parse rdata for config: ' . $line,
610
+ Net_DNS2_Lookups::E_PARSE_ERROR
611
+ );
612
+ }
613
+
614
+ } else {
615
+
616
+ throw new Net_DNS2_Exception(
617
+ 'failed to create new RR record for type: ' . $type,
618
+ Net_DNS2_Lookups::E_RR_INVALID
619
+ );
620
+ }
621
+
622
+ } else {
623
+
624
+ throw new Net_DNS2_Exception(
625
+ 'un-implemented resource record type: '. $type,
626
+ Net_DNS2_Lookups::E_RR_INVALID
627
+ );
628
+ }
629
+
630
+ return $o;
631
+ }
632
+ }
633
+
634
+ /*
635
+ * Local variables:
636
+ * tab-width: 4
637
+ * c-basic-offset: 4
638
+ * c-hanging-comment-ender-p: nil
639
+ * End:
640
+ */
641
+ ?>
includes/Net/DNS2/RR/A.php ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * A Resource Record - RFC1035 section 3.4.1
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | ADDRESS |
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ *
59
+ * @category Networking
60
+ * @package Net_DNS2
61
+ * @author Mike Pultz <mike@mikepultz.com>
62
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
63
+ * @link http://pear.php.net/package/Net_DNS2
64
+ * @see Net_DNS2_RR
65
+ *
66
+ */
67
+ class Net_DNS2_RR_A extends Net_DNS2_RR
68
+ {
69
+ /*
70
+ * The IPv4 address in quad-dotted notation
71
+ */
72
+ public $address;
73
+
74
+ /**
75
+ * method to return the rdata portion of the packet as a string
76
+ *
77
+ * @return string
78
+ * @access protected
79
+ *
80
+ */
81
+ protected function rrToString()
82
+ {
83
+ return $this->address;
84
+ }
85
+
86
+ /**
87
+ * parses the rdata portion from a standard DNS config line
88
+ *
89
+ * @param array $rdata a string split line of values for the rdata
90
+ *
91
+ * @return boolean
92
+ * @access protected
93
+ *
94
+ */
95
+ protected function rrFromString(array $rdata)
96
+ {
97
+ $value = array_shift($rdata);
98
+
99
+ if (Net_DNS2::isIPv4($value) == true) {
100
+
101
+ $this->address = $value;
102
+ return true;
103
+ }
104
+
105
+ return false;
106
+ }
107
+
108
+ /**
109
+ * parses the rdata of the Net_DNS2_Packet object
110
+ *
111
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
112
+ *
113
+ * @return boolean
114
+ * @access protected
115
+ *
116
+ */
117
+ protected function rrSet(Net_DNS2_Packet &$packet)
118
+ {
119
+ if ($this->rdlength > 0) {
120
+
121
+ $this->address = inet_ntop($this->rdata);
122
+ if ($this->address !== false) {
123
+
124
+ return true;
125
+ }
126
+ }
127
+
128
+ return false;
129
+ }
130
+
131
+ /**
132
+ * returns the rdata portion of the DNS packet
133
+ *
134
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
135
+ * compressed names
136
+ *
137
+ * @return mixed either returns a binary packed
138
+ * string or null on failure
139
+ * @access protected
140
+ *
141
+ */
142
+ protected function rrGet(Net_DNS2_Packet &$packet)
143
+ {
144
+ $packet->offset += 4;
145
+ return inet_pton($this->address);
146
+ }
147
+ }
148
+
149
+ /*
150
+ * Local variables:
151
+ * tab-width: 4
152
+ * c-basic-offset: 4
153
+ * c-hanging-comment-ender-p: nil
154
+ * End:
155
+ */
156
+ ?>
includes/Net/DNS2/RR/AAAA.php ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * A Resource Record - RFC1035 section 3.4.1
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | |
57
+ * | |
58
+ * | |
59
+ * | ADDRESS |
60
+ * | |
61
+ * | (128 bit) |
62
+ * | |
63
+ * | |
64
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
65
+ *
66
+ * @category Networking
67
+ * @package Net_DNS2
68
+ * @author Mike Pultz <mike@mikepultz.com>
69
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
70
+ * @link http://pear.php.net/package/Net_DNS2
71
+ * @see Net_DNS2_RR
72
+ *
73
+ */
74
+ class Net_DNS2_RR_AAAA extends Net_DNS2_RR
75
+ {
76
+ /*
77
+ * the IPv6 address in the preferred hexadecimal values of the eight
78
+ * 16-bit pieces
79
+ * per RFC1884
80
+ *
81
+ */
82
+ public $address;
83
+
84
+ /**
85
+ * method to return the rdata portion of the packet as a string
86
+ *
87
+ * @return string
88
+ * @access protected
89
+ *
90
+ */
91
+ protected function rrToString()
92
+ {
93
+ return $this->address;
94
+ }
95
+
96
+ /**
97
+ * parses the rdata portion from a standard DNS config line
98
+ *
99
+ * @param array $rdata a string split line of values for the rdata
100
+ *
101
+ * @return boolean
102
+ * @access protected
103
+ *
104
+ */
105
+ protected function rrFromString(array $rdata)
106
+ {
107
+ //
108
+ // expand out compressed formats
109
+ //
110
+ $value = array_shift($rdata);
111
+ if (Net_DNS2::isIPv6($value) == true) {
112
+
113
+ $this->address = $value;
114
+ return true;
115
+ }
116
+
117
+ return false;
118
+ }
119
+
120
+ /**
121
+ * parses the rdata of the Net_DNS2_Packet object
122
+ *
123
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
124
+ *
125
+ * @return boolean
126
+ * @access protected
127
+ *
128
+ */
129
+ protected function rrSet(Net_DNS2_Packet &$packet)
130
+ {
131
+ //
132
+ // must be 8 x 16bit chunks, or 16 x 8bit
133
+ //
134
+ if ($this->rdlength == 16) {
135
+
136
+ //
137
+ // PHP's inet_ntop returns IPv6 addresses in their compressed form,
138
+ // but we want to keep with the preferred standard, so we'll parse
139
+ // it manually.
140
+ //
141
+ $x = unpack('n8', $this->rdata);
142
+ if (count($x) == 8) {
143
+
144
+ $this->address = vsprintf('%x:%x:%x:%x:%x:%x:%x:%x', $x);
145
+ return true;
146
+ }
147
+ }
148
+
149
+ return false;
150
+ }
151
+
152
+ /**
153
+ * returns the rdata portion of the DNS packet
154
+ *
155
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
156
+ * compressed names
157
+ *
158
+ * @return mixed either returns a binary packed
159
+ * string or null on failure
160
+ * @access protected
161
+ *
162
+ */
163
+ protected function rrGet(Net_DNS2_Packet &$packet)
164
+ {
165
+ $packet->offset += 16;
166
+ return inet_pton($this->address);
167
+ }
168
+ }
169
+
170
+ /*
171
+ * Local variables:
172
+ * tab-width: 4
173
+ * c-basic-offset: 4
174
+ * c-hanging-comment-ender-p: nil
175
+ * End:
176
+ */
177
+ ?>
includes/Net/DNS2/RR/AFSDB.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * AFSDB Resource Record - RFC1183 section 1
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | SUBTYPE |
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * / HOSTNAME /
59
+ * / /
60
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
61
+ *
62
+ * @category Networking
63
+ * @package Net_DNS2
64
+ * @author Mike Pultz <mike@mikepultz.com>
65
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
66
+ * @link http://pear.php.net/package/Net_DNS2
67
+ * @see Net_DNS2_RR
68
+ *
69
+ */
70
+ class Net_DNS2_RR_AFSDB extends Net_DNS2_RR
71
+ {
72
+ /*
73
+ * The AFSDB sub type
74
+ */
75
+ public $subtype;
76
+
77
+ /*
78
+ * The AFSDB hostname
79
+ */
80
+ public $hostname;
81
+
82
+ /**
83
+ * method to return the rdata portion of the packet as a string
84
+ *
85
+ * @return string
86
+ * @access protected
87
+ *
88
+ */
89
+ protected function rrToString()
90
+ {
91
+ return $this->subtype . ' ' . $this->cleanString($this->hostname) . '.';
92
+ }
93
+
94
+ /**
95
+ * parses the rdata portion from a standard DNS config line
96
+ *
97
+ * @param array $rdata a string split line of values for the rdata
98
+ *
99
+ * @return boolean
100
+ * @access protected
101
+ *
102
+ */
103
+ protected function rrFromString(array $rdata)
104
+ {
105
+ $this->subtype = array_shift($rdata);
106
+ $this->hostname = $this->cleanString(array_shift($rdata));
107
+
108
+ return true;
109
+ }
110
+
111
+ /**
112
+ * parses the rdata of the Net_DNS2_Packet object
113
+ *
114
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
115
+ *
116
+ * @return boolean
117
+ * @access protected
118
+ *
119
+ */
120
+ protected function rrSet(Net_DNS2_Packet &$packet)
121
+ {
122
+ if ($this->rdlength > 0) {
123
+
124
+ //
125
+ // unpack the subtype
126
+ //
127
+ $x = unpack('nsubtype', $this->rdata);
128
+
129
+ $this->subtype = $x['subtype'];
130
+ $offset = $packet->offset + 2;
131
+
132
+ $this->hostname = Net_DNS2_Packet::expand($packet, $offset);
133
+
134
+ return true;
135
+ }
136
+
137
+ return false;
138
+ }
139
+
140
+ /**
141
+ * returns the rdata portion of the DNS packet
142
+ *
143
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
144
+ * compressed names
145
+ *
146
+ * @return mixed either returns a binary packed
147
+ * string or null on failure
148
+ * @access protected
149
+ *
150
+ */
151
+ protected function rrGet(Net_DNS2_Packet &$packet)
152
+ {
153
+ if (strlen($this->hostname) > 0) {
154
+
155
+ $data = pack('n', $this->subtype);
156
+ $packet->offset += 2;
157
+
158
+ $data .= $packet->compress($this->hostname, $packet->offset);
159
+
160
+ return $data;
161
+ }
162
+
163
+ return null;
164
+ }
165
+ }
166
+
167
+ /*
168
+ * Local variables:
169
+ * tab-width: 4
170
+ * c-basic-offset: 4
171
+ * c-hanging-comment-ender-p: nil
172
+ * End:
173
+ */
174
+ ?>
includes/Net/DNS2/RR/ANY.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * This is only used for generating an empty ANY RR.
54
+ *
55
+ * @category Networking
56
+ * @package Net_DNS2
57
+ * @author Mike Pultz <mike@mikepultz.com>
58
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
59
+ * @link http://pear.php.net/package/Net_DNS2
60
+ * @see Net_DNS2_RR
61
+ *
62
+ */
63
+ class Net_DNS2_RR_ANY extends Net_DNS2_RR
64
+ {
65
+ /**
66
+ * method to return the rdata portion of the packet as a string
67
+ *
68
+ * @return string
69
+ * @access protected
70
+ *
71
+ */
72
+ protected function rrToString()
73
+ {
74
+ return '';
75
+ }
76
+
77
+ /**
78
+ * parses the rdata portion from a standard DNS config line
79
+ *
80
+ * @param array $rdata a string split line of values for the rdata
81
+ *
82
+ * @return boolean
83
+ * @access protected
84
+ *
85
+ */
86
+ protected function rrFromString(array $rdata)
87
+ {
88
+ return true;
89
+ }
90
+
91
+ /**
92
+ * parses the rdata of the Net_DNS2_Packet object
93
+ *
94
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
95
+ *
96
+ * @return boolean
97
+ * @access protected
98
+ *
99
+ */
100
+ protected function rrSet(Net_DNS2_Packet &$packet)
101
+ {
102
+ return true;
103
+ }
104
+
105
+ /**
106
+ * returns the rdata portion of the DNS packet
107
+ *
108
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
109
+ * compressed names
110
+ *
111
+ * @return mixed either returns a binary packed
112
+ * string or null on failure
113
+ * @access protected
114
+ *
115
+ */
116
+ protected function rrGet(Net_DNS2_Packet &$packet)
117
+ {
118
+ return '';
119
+ }
120
+ }
121
+
122
+ /*
123
+ * Local variables:
124
+ * tab-width: 4
125
+ * c-basic-offset: 4
126
+ * c-hanging-comment-ender-p: nil
127
+ * End:
128
+ */
129
+ ?>
includes/Net/DNS2/RR/APL.php ADDED
@@ -0,0 +1,343 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.0.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * APL Resource Record - RFC3123
54
+ *
55
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
56
+ * | ADDRESSFAMILY |
57
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
58
+ * | PREFIX | N | AFDLENGTH |
59
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
60
+ * / AFDPART /
61
+ * | |
62
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
63
+ *
64
+ * @category Networking
65
+ * @package Net_DNS2
66
+ * @author Mike Pultz <mike@mikepultz.com>
67
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
68
+ * @link http://pear.php.net/package/Net_DNS2
69
+ * @see Net_DNS2_RR
70
+ *
71
+ */
72
+ class Net_DNS2_RR_APL extends Net_DNS2_RR
73
+ {
74
+ /*
75
+ * a list of all the address prefix list items
76
+ */
77
+ public $apl_items = array();
78
+
79
+ /**
80
+ * method to return the rdata portion of the packet as a string
81
+ *
82
+ * @return string
83
+ * @access protected
84
+ *
85
+ */
86
+ protected function rrToString()
87
+ {
88
+ $out = '';
89
+
90
+ foreach ($this->apl_items as $item) {
91
+
92
+ if ($item['n'] == 1) {
93
+
94
+ $out .= '!';
95
+ }
96
+
97
+ $out .= $item['address_family'] . ':' .
98
+ $item['afd_part'] . '/' . $item['prefix'] . ' ';
99
+ }
100
+
101
+ return trim($out);
102
+ }
103
+
104
+ /**
105
+ * parses the rdata portion from a standard DNS config line
106
+ *
107
+ * @param array $rdata a string split line of values for the rdata
108
+ *
109
+ * @return boolean
110
+ * @access protected
111
+ *
112
+ */
113
+ protected function rrFromString(array $rdata)
114
+ {
115
+ foreach ($rdata as $item) {
116
+
117
+ if (preg_match('/^(!?)([1|2])\:([^\/]*)\/([0-9]{1,3})$/', $item, $m)) {
118
+
119
+ $i = array(
120
+
121
+ 'address_family' => $m[2],
122
+ 'prefix' => $m[4],
123
+ 'n' => ($m[1] == '!') ? 1 : 0,
124
+ 'afd_part' => strtolower($m[3])
125
+ );
126
+
127
+ $address = $this->_trimZeros(
128
+ $i['address_family'], $i['afd_part']
129
+ );
130
+
131
+ $i['afd_length'] = count(explode('.', $address));
132
+
133
+ $this->apl_items[] = $i;
134
+ }
135
+ }
136
+
137
+ return true;
138
+ }
139
+
140
+ /**
141
+ * parses the rdata of the Net_DNS2_Packet object
142
+ *
143
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
144
+ *
145
+ * @return boolean
146
+ * @access protected
147
+ *
148
+ */
149
+ protected function rrSet(Net_DNS2_Packet &$packet)
150
+ {
151
+ if ($this->rdlength > 0) {
152
+
153
+ $offset = 0;
154
+
155
+ while ($offset < $this->rdlength) {
156
+
157
+ //
158
+ // unpack the family, prefix, negate and length values
159
+ //
160
+ $x = unpack(
161
+ 'naddress_family/Cprefix/Cextra', substr($this->rdata, $offset)
162
+ );
163
+
164
+ $item = array(
165
+
166
+ 'address_family' => $x['address_family'],
167
+ 'prefix' => $x['prefix'],
168
+ 'n' => ($x['extra'] >> 7) & 0x1,
169
+ 'afd_length' => $x['extra'] & 0xf
170
+ );
171
+
172
+ switch($item['address_family']) {
173
+
174
+ case 1:
175
+ $r = unpack(
176
+ 'C*', substr($this->rdata, $offset + 4, $item['afd_length'])
177
+ );
178
+ if (count($r) < 4) {
179
+
180
+ for ($c=count($r)+1; $c<4+1; $c++) {
181
+
182
+ $r[$c] = 0;
183
+ }
184
+ }
185
+
186
+ $item['afd_part'] = implode('.', $r);
187
+
188
+ break;
189
+ case 2:
190
+ $r = unpack(
191
+ 'C*', substr($this->rdata, $offset + 4, $item['afd_length'])
192
+ );
193
+ if (count($r) < 8) {
194
+
195
+ for ($c=count($r)+1; $c<8+1; $c++) {
196
+
197
+ $r[$c] = 0;
198
+ }
199
+ }
200
+
201
+ $item['afd_part'] = sprintf(
202
+ '%x:%x:%x:%x:%x:%x:%x:%x',
203
+ $r[1], $r[2], $r[3], $r[4], $r[5], $r[6], $r[7], $r[8]
204
+ );
205
+
206
+ break;
207
+ default:
208
+ return false;
209
+ }
210
+
211
+ $this->apl_items[] = $item;
212
+
213
+ $offset += 4 + $item['afd_length'];
214
+ }
215
+
216
+ return true;
217
+ }
218
+
219
+ return false;
220
+ }
221
+
222
+ /**
223
+ * returns the rdata portion of the DNS packet
224
+ *
225
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
226
+ * compressed names
227
+ *
228
+ * @return mixed either returns a binary packed
229
+ * string or null on failure
230
+ * @access protected
231
+ *
232
+ */
233
+ protected function rrGet(Net_DNS2_Packet &$packet)
234
+ {
235
+ if (count($this->apl_items) > 0) {
236
+
237
+ $data = '';
238
+
239
+ foreach ($this->apl_items as $item) {
240
+
241
+ //
242
+ // pack the address_family and prefix values
243
+ //
244
+ $data .= pack(
245
+ 'nCC',
246
+ $item['address_family'],
247
+ $item['prefix'],
248
+ ($item['n'] << 7) | $item['afd_length']
249
+ );
250
+
251
+ switch($item['address_family']) {
252
+ case 1:
253
+ $address = explode(
254
+ '.',
255
+ $this->_trimZeros($item['address_family'], $item['afd_part'])
256
+ );
257
+
258
+ foreach ($address as $b) {
259
+ $data .= chr($b);
260
+ }
261
+ break;
262
+ case 2:
263
+ $address = explode(
264
+ ':',
265
+ $this->_trimZeros($item['address_family'], $item['afd_part'])
266
+ );
267
+
268
+ foreach ($address as $b) {
269
+ $data .= pack('H', $b);
270
+ }
271
+ break;
272
+ default:
273
+ return null;
274
+ }
275
+ }
276
+
277
+ $packet->offset += strlen($data);
278
+
279
+ return $data;
280
+ }
281
+
282
+ return null;
283
+ }
284
+
285
+ /**
286
+ * returns an IP address with the right-hand zero's trimmed
287
+ *
288
+ * @param integer $family the IP address family from the rdata
289
+ * @param string $address the IP address
290
+ *
291
+ * @return string the trimmed IP addresss.
292
+ *
293
+ * @access private
294
+ *
295
+ */
296
+ private function _trimZeros($family, $address)
297
+ {
298
+ $a = array();
299
+
300
+ switch($family) {
301
+ case 1:
302
+ $a = array_reverse(explode('.', $address));
303
+ break;
304
+ case 2:
305
+ $a = array_reverse(explode(':', $address));
306
+ break;
307
+ default:
308
+ return '';
309
+ }
310
+
311
+ foreach ($a as $value) {
312
+
313
+ if ($value === '0') {
314
+
315
+ array_shift($a);
316
+ }
317
+ }
318
+
319
+ $out = '';
320
+
321
+ switch($family) {
322
+ case 1:
323
+ $out = implode('.', array_reverse($a));
324
+ break;
325
+ case 2:
326
+ $out = implode(':', array_reverse($a));
327
+ break;
328
+ default:
329
+ return '';
330
+ }
331
+
332
+ return $out;
333
+ }
334
+ }
335
+
336
+ /*
337
+ * Local variables:
338
+ * tab-width: 4
339
+ * c-basic-offset: 4
340
+ * c-hanging-comment-ender-p: nil
341
+ * End:
342
+ */
343
+ ?>
includes/Net/DNS2/RR/ATMA.php ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.1.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * ATMA Resource Record
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
56
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
57
+ * | FORMAT | |
58
+ * | +--+--+--+--+--+--+--+--+
59
+ * / ADDRESS /
60
+ * | |
61
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
62
+ *
63
+ * @category Networking
64
+ * @package Net_DNS2
65
+ * @author Mike Pultz <mike@mikepultz.com>
66
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
67
+ * @link http://pear.php.net/package/Net_DNS2
68
+ * @see Net_DNS2_RR
69
+ *
70
+ */
71
+ class Net_DNS2_RR_ATMA extends Net_DNS2_RR
72
+ {
73
+ /*
74
+ * One octet that indicates the format of ADDRESS. The two possible values
75
+ * for FORMAT are value 0 indicating ATM End System Address (AESA) format
76
+ * and value 1 indicating E.164 format
77
+ */
78
+ public $format;
79
+
80
+ /*
81
+ * The IPv4 address in quad-dotted notation
82
+ */
83
+ public $address;
84
+
85
+ /**
86
+ * method to return the rdata portion of the packet as a string
87
+ *
88
+ * @return string
89
+ * @access protected
90
+ *
91
+ */
92
+ protected function rrToString()
93
+ {
94
+ return $this->address;
95
+ }
96
+
97
+ /**
98
+ * parses the rdata portion from a standard DNS config line
99
+ *
100
+ * @param array $rdata a string split line of values for the rdata
101
+ *
102
+ * @return boolean
103
+ * @access protected
104
+ *
105
+ */
106
+ protected function rrFromString(array $rdata)
107
+ {
108
+ $value = array_shift($rdata);
109
+
110
+ if (ctype_xdigit($value) == true) {
111
+
112
+ $this->format = 0;
113
+ $this->address = $value;
114
+
115
+ } else if (is_numeric($value) == true) {
116
+
117
+ $this->format = 1;
118
+ $this->address = $value;
119
+
120
+ } else {
121
+
122
+ return false;
123
+ }
124
+
125
+ return true;
126
+ }
127
+
128
+ /**
129
+ * parses the rdata of the Net_DNS2_Packet object
130
+ *
131
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
132
+ *
133
+ * @return boolean
134
+ * @access protected
135
+ *
136
+ */
137
+ protected function rrSet(Net_DNS2_Packet &$packet)
138
+ {
139
+ if ($this->rdlength > 0) {
140
+
141
+ //
142
+ // unpack the format
143
+ //
144
+ $x = unpack('Cformat/N*address', $this->rdata);
145
+
146
+ $this->format = $x['format'];
147
+
148
+ if ($this->format == 0) {
149
+
150
+ $a = unpack('@1/H*address', $this->rdata);
151
+
152
+ $this->address = $a['address'];
153
+
154
+ } else if ($this->format == 1) {
155
+
156
+ $this->address = substr($this->rdata, 1, $this->rdlength - 1);
157
+
158
+ } else {
159
+
160
+ return false;
161
+ }
162
+
163
+ return true;
164
+ }
165
+
166
+ return false;
167
+ }
168
+
169
+ /**
170
+ * returns the rdata portion of the DNS packet
171
+ *
172
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
173
+ * compressed names
174
+ *
175
+ * @return mixed either returns a binary packed
176
+ * string or null on failure
177
+ * @access protected
178
+ *
179
+ */
180
+ protected function rrGet(Net_DNS2_Packet &$packet)
181
+ {
182
+ $data = chr($this->format);
183
+
184
+ if ($this->format == 0) {
185
+
186
+ $data .= pack('H*', $this->address);
187
+
188
+ } else if ($this->format == 1) {
189
+
190
+ $data .= $this->address;
191
+
192
+ } else {
193
+
194
+ return null;
195
+ }
196
+
197
+ $packet->offset += strlen($data);
198
+
199
+ return $data;
200
+ }
201
+ }
202
+
203
+ /*
204
+ * Local variables:
205
+ * tab-width: 4
206
+ * c-basic-offset: 4
207
+ * c-hanging-comment-ender-p: nil
208
+ * End:
209
+ */
210
+ ?>
includes/Net/DNS2/RR/CAA.php ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2011, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2011 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.2.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * CAA Resource Record - http://tools.ietf.org/html/draft-ietf-pkix-caa-03
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | FLAGS | TAG LENGTH |
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * / TAG /
59
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
60
+ * / DATA /
61
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
62
+ *
63
+ * @category Networking
64
+ * @package Net_DNS2
65
+ * @author Mike Pultz <mike@mikepultz.com>
66
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
67
+ * @link http://pear.php.net/package/Net_DNS2
68
+ * @see Net_DNS2_RR
69
+ *
70
+ */
71
+ class Net_DNS2_RR_CAA extends Net_DNS2_RR
72
+ {
73
+ /*
74
+ * The critcal flag
75
+ */
76
+ public $flags;
77
+
78
+ /*
79
+ * The property identifier
80
+ */
81
+ public $tag;
82
+
83
+ /*
84
+ * The property value
85
+ */
86
+ public $value;
87
+
88
+ /**
89
+ * method to return the rdata portion of the packet as a string
90
+ *
91
+ * @return string
92
+ * @access protected
93
+ *
94
+ */
95
+ protected function rrToString()
96
+ {
97
+ return $this->flags . ' ' . $this->tag . ' "' .
98
+ trim($this->cleanString($this->value), '"') . '"';
99
+ }
100
+
101
+ /**
102
+ * parses the rdata portion from a standard DNS config line
103
+ *
104
+ * @param array $rdata a string split line of values for the rdata
105
+ *
106
+ * @return boolean
107
+ * @access protected
108
+ *
109
+ */
110
+ protected function rrFromString(array $rdata)
111
+ {
112
+ $this->flags = array_shift($rdata);
113
+ $this->tag = array_shift($rdata);
114
+
115
+ $this->value = trim($this->cleanString(implode($rdata, ' ')), '"');
116
+
117
+ return true;
118
+ }
119
+
120
+ /**
121
+ * parses the rdata of the Net_DNS2_Packet object
122
+ *
123
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
124
+ *
125
+ * @return boolean
126
+ * @access protected
127
+ *
128
+ */
129
+ protected function rrSet(Net_DNS2_Packet &$packet)
130
+ {
131
+ if ($this->rdlength > 0) {
132
+
133
+ //
134
+ // unpack the flags and tag length
135
+ //
136
+ $x = unpack('Cflags/Ctag_length', $this->rdata);
137
+
138
+ $this->flags = $x['flags'];
139
+ $offset = 2;
140
+
141
+ $this->tag = substr($this->rdata, $offset, $x['tag_length']);
142
+ $offset += $x['tag_length'];
143
+
144
+ $this->value = substr($this->rdata, $offset);
145
+
146
+ return true;
147
+ }
148
+
149
+ return false;
150
+ }
151
+
152
+ /**
153
+ * returns the rdata portion of the DNS packet
154
+ *
155
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
156
+ * compressed names
157
+ *
158
+ * @return mixed either returns a binary packed
159
+ * string or null on failure
160
+ * @access protected
161
+ *
162
+ */
163
+ protected function rrGet(Net_DNS2_Packet &$packet)
164
+ {
165
+ if (strlen($this->value) > 0) {
166
+
167
+ $data = chr($this->flags);
168
+ $data .= chr(strlen($this->tag)) . $this->tag . $this->value;
169
+
170
+ $packet->offset += strlen($data);
171
+
172
+ return $data;
173
+ }
174
+
175
+ return null;
176
+ }
177
+ }
178
+
179
+ ?>
includes/Net/DNS2/RR/CDNSKEY.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2014, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2014 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.4.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * The CDNSKEY RR is implemented exactly like the DNSKEY record, so
54
+ * for now we just extend the DNSKEY RR and use it.
55
+ *
56
+ * http://www.rfc-editor.org/rfc/rfc7344.txt
57
+ *
58
+ * @category Networking
59
+ * @package Net_DNS2
60
+ * @author Mike Pultz <mike@mikepultz.com>
61
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
62
+ * @link http://pear.php.net/package/Net_DNS2
63
+ * @see Net_DNS2_RR
64
+ *
65
+ */
66
+ class Net_DNS2_RR_CDNSKEY extends Net_DNS2_RR_DNSKEY
67
+ {
68
+ }
69
+
70
+ /*
71
+ * Local variables:
72
+ * tab-width: 4
73
+ * c-basic-offset: 4
74
+ * c-hanging-comment-ender-p: nil
75
+ * End:
76
+ */
77
+ ?>
includes/Net/DNS2/RR/CDS.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2011, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2011 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.2.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * The CDS RR is implemented exactly like the DS record, so
54
+ * for now we just extend the DS RR and use it.
55
+ *
56
+ * http://www.rfc-editor.org/rfc/rfc7344.txt
57
+ *
58
+ * @category Networking
59
+ * @package Net_DNS2
60
+ * @author Mike Pultz <mike@mikepultz.com>
61
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
62
+ * @link http://pear.php.net/package/Net_DNS2
63
+ * @see Net_DNS2_RR
64
+ *
65
+ */
66
+ class Net_DNS2_RR_CDS extends Net_DNS2_RR_DS
67
+ {
68
+ }
69
+
70
+ /*
71
+ * Local variables:
72
+ * tab-width: 4
73
+ * c-basic-offset: 4
74
+ * c-hanging-comment-ender-p: nil
75
+ * End:
76
+ */
77
+ ?>
includes/Net/DNS2/RR/CERT.php ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * CERT Resource Record - RFC4398 section 2
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | format | key tag |
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59
+ * | algorithm | /
60
+ * +---------------+ certificate or CRL /
61
+ * / /
62
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
63
+ *
64
+ * @category Networking
65
+ * @package Net_DNS2
66
+ * @author Mike Pultz <mike@mikepultz.com>
67
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
68
+ * @link http://pear.php.net/package/Net_DNS2
69
+ * @see Net_DNS2_RR
70
+ *
71
+ */
72
+ class Net_DNS2_RR_CERT extends Net_DNS2_RR
73
+ {
74
+ /*
75
+ * format's allowed for certificates
76
+ */
77
+ const CERT_FORMAT_RES = 0;
78
+ const CERT_FORMAT_PKIX = 1;
79
+ const CERT_FORMAT_SPKI = 2;
80
+ const CERT_FORMAT_PGP = 3;
81
+ const CERT_FORMAT_IPKIX = 4;
82
+ const CERT_FORMAT_ISPKI = 5;
83
+ const CERT_FORMAT_IPGP = 6;
84
+ const CERT_FORMAT_ACPKIX = 7;
85
+ const CERT_FORMAT_IACPKIX = 8;
86
+ const CERT_FORMAT_URI = 253;
87
+ const CERT_FORMAT_OID = 254;
88
+
89
+ public $cert_format_name_to_id = array();
90
+ public $cert_format_id_to_name = array(
91
+
92
+ self::CERT_FORMAT_RES => 'Reserved',
93
+ self::CERT_FORMAT_PKIX => 'PKIX',
94
+ self::CERT_FORMAT_SPKI => 'SPKI',
95
+ self::CERT_FORMAT_PGP => 'PGP',
96
+ self::CERT_FORMAT_IPKIX => 'IPKIX',
97
+ self::CERT_FORMAT_ISPKI => 'ISPKI',
98
+ self::CERT_FORMAT_IPGP => 'IPGP',
99
+ self::CERT_FORMAT_ACPKIX => 'ACPKIX',
100
+ self::CERT_FORMAT_IACPKIX => 'IACPKIX',
101
+ self::CERT_FORMAT_URI => 'URI',
102
+ self::CERT_FORMAT_OID => 'OID'
103
+ );
104
+
105
+ /*
106
+ * certificate format
107
+ */
108
+ public $format;
109
+
110
+ /*
111
+ * key tag
112
+ */
113
+ public $keytag;
114
+
115
+ /*
116
+ * The algorithm used for the CERt
117
+ */
118
+ public $algorithm;
119
+
120
+ /*
121
+ * certificate
122
+ */
123
+ public $certificate;
124
+
125
+ /**
126
+ * we have our own constructor so that we can load our certificate
127
+ * information for parsing.
128
+ *
129
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
130
+ * @param array $rr a array with parsed RR values
131
+ *
132
+ * @return
133
+ *
134
+ */
135
+ public function __construct(Net_DNS2_Packet &$packet = null, array $rr = null)
136
+ {
137
+ parent::__construct($packet, $rr);
138
+
139
+ //
140
+ // load the lookup values
141
+ //
142
+ $this->cert_format_name_to_id = array_flip($this->cert_format_id_to_name);
143
+ }
144
+
145
+ /**
146
+ * method to return the rdata portion of the packet as a string
147
+ *
148
+ * @return string
149
+ * @access protected
150
+ *
151
+ */
152
+ protected function rrToString()
153
+ {
154
+ return $this->format . ' ' . $this->keytag . ' ' . $this->algorithm .
155
+ ' ' . base64_encode($this->certificate);
156
+ }
157
+
158
+ /**
159
+ * parses the rdata portion from a standard DNS config line
160
+ *
161
+ * @param array $rdata a string split line of values for the rdata
162
+ *
163
+ * @return boolean
164
+ * @access protected
165
+ *
166
+ */
167
+ protected function rrFromString(array $rdata)
168
+ {
169
+ //
170
+ // load and check the format; can be an int, or a mnemonic symbol
171
+ //
172
+ $this->format = array_shift($rdata);
173
+ if (!is_numeric($this->format)) {
174
+
175
+ $mnemonic = strtoupper(trim($this->format));
176
+ if (!isset($this->cert_format_name_to_id[$mnemonic])) {
177
+
178
+ return false;
179
+ }
180
+
181
+ $this->format = $this->cert_format_name_to_id[$mnemonic];
182
+ } else {
183
+
184
+ if (!isset($this->cert_format_id_to_name[$this->format])) {
185
+
186
+ return false;
187
+ }
188
+ }
189
+
190
+ $this->keytag = array_shift($rdata);
191
+
192
+ //
193
+ // parse and check the algorithm; can be an int, or a mnemonic symbol
194
+ //
195
+ $this->algorithm = array_shift($rdata);
196
+ if (!is_numeric($this->algorithm)) {
197
+
198
+ $mnemonic = strtoupper(trim($this->algorithm));
199
+ if (!isset(Net_DNS2_Lookups::$algorithm_name_to_id[$mnemonic])) {
200
+
201
+ return false;
202
+ }
203
+
204
+ $this->algorithm = Net_DNS2_Lookups::$algorithm_name_to_id[
205
+ $mnemonic
206
+ ];
207
+ } else {
208
+
209
+ if (!isset(Net_DNS2_Lookups::$algorithm_id_to_name[$this->algorithm])) {
210
+ return false;
211
+ }
212
+ }
213
+
214
+ //
215
+ // parse and base64 decode the certificate
216
+ //
217
+ // certificates MUST be provided base64 encoded, if not, everything will
218
+ // be broken after this point, as we assume it's base64 encoded.
219
+ //
220
+ $this->certificate = base64_decode(implode(' ', $rdata));
221
+
222
+ return true;
223
+ }
224
+
225
+ /**
226
+ * parses the rdata of the Net_DNS2_Packet object
227
+ *
228
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
229
+ *
230
+ * @return boolean
231
+ * @access protected
232
+ *
233
+ */
234
+ protected function rrSet(Net_DNS2_Packet &$packet)
235
+ {
236
+ if ($this->rdlength > 0) {
237
+
238
+ //
239
+ // unpack the format, keytag and algorithm
240
+ //
241
+ $x = unpack('nformat/nkeytag/Calgorithm', $this->rdata);
242
+
243
+ $this->format = $x['format'];
244
+ $this->keytag = $x['keytag'];
245
+ $this->algorithm = $x['algorithm'];
246
+
247
+ //
248
+ // copy the certificate
249
+ //
250
+ $this->certificate = substr($this->rdata, 5, $this->rdlength - 5);
251
+
252
+ return true;
253
+ }
254
+
255
+ return false;
256
+ }
257
+
258
+ /**
259
+ * returns the rdata portion of the DNS packet
260
+ *
261
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
262
+ * compressed names
263
+ *
264
+ * @return mixed either returns a binary packed
265
+ * string or null on failure
266
+ * @access protected
267
+ *
268
+ */
269
+ protected function rrGet(Net_DNS2_Packet &$packet)
270
+ {
271
+ if (strlen($this->certificate) > 0) {
272
+
273
+ $data = pack('nnC', $this->format, $this->keytag, $this->algorithm) .
274
+ $this->certificate;
275
+
276
+ $packet->offset += strlen($data);
277
+
278
+ return $data;
279
+ }
280
+
281
+ return null;
282
+ }
283
+ }
284
+
285
+ /*
286
+ * Local variables:
287
+ * tab-width: 4
288
+ * c-basic-offset: 4
289
+ * c-hanging-comment-ender-p: nil
290
+ * End:
291
+ */
292
+ ?>
includes/Net/DNS2/RR/CNAME.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * CNAME Resource Record - RFC1035 section 3.3.1
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * / CNAME /
57
+ * / /
58
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
59
+ *
60
+ * @category Networking
61
+ * @package Net_DNS2
62
+ * @author Mike Pultz <mike@mikepultz.com>
63
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
64
+ * @link http://pear.php.net/package/Net_DNS2
65
+ * @see Net_DNS2_RR
66
+ *
67
+ */
68
+ class Net_DNS2_RR_CNAME extends Net_DNS2_RR
69
+ {
70
+ /*
71
+ * The canonical name
72
+ */
73
+ public $cname;
74
+
75
+ /**
76
+ * method to return the rdata portion of the packet as a string
77
+ *
78
+ * @return string
79
+ * @access protected
80
+ *
81
+ */
82
+ protected function rrToString()
83
+ {
84
+ return $this->cleanString($this->cname) . '.';
85
+ }
86
+
87
+ /**
88
+ * parses the rdata portion from a standard DNS config line
89
+ *
90
+ * @param array $rdata a string split line of values for the rdata
91
+ *
92
+ * @return boolean
93
+ * @access protected
94
+ *
95
+ */
96
+ protected function rrFromString(array $rdata)
97
+ {
98
+ $this->cname = $this->cleanString(array_shift($rdata));
99
+ return true;
100
+ }
101
+
102
+ /**
103
+ * parses the rdata of the Net_DNS2_Packet object
104
+ *
105
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
106
+ *
107
+ * @return boolean
108
+ * @access protected
109
+ *
110
+ */
111
+ protected function rrSet(Net_DNS2_Packet &$packet)
112
+ {
113
+ if ($this->rdlength > 0) {
114
+
115
+ $offset = $packet->offset;
116
+ $this->cname = Net_DNS2_Packet::expand($packet, $offset);
117
+
118
+ return true;
119
+ }
120
+
121
+ return false;
122
+ }
123
+
124
+ /**
125
+ * returns the rdata portion of the DNS packet
126
+ *
127
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
128
+ * compressed names
129
+ *
130
+ * @return mixed either returns a binary packed
131
+ * string or null on failure
132
+ * @access protected
133
+ *
134
+ */
135
+ protected function rrGet(Net_DNS2_Packet &$packet)
136
+ {
137
+ if (strlen($this->cname) > 0) {
138
+
139
+ return $packet->compress($this->cname, $packet->offset);
140
+ }
141
+
142
+ return null;
143
+ }
144
+ }
145
+
146
+ /*
147
+ * Local variables:
148
+ * tab-width: 4
149
+ * c-basic-offset: 4
150
+ * c-hanging-comment-ender-p: nil
151
+ * End:
152
+ */
153
+ ?>
includes/Net/DNS2/RR/CSYNC.php ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2015, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2015 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.4.1
49
+ *
50
+ */
51
+
52
+ /**
53
+ * CSYNC Resource Record - RFC 7477 seciond 2.1.1
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | SOA Serial |
57
+ * | |
58
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
59
+ * | Flags |
60
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
61
+ * / Type Bit Map /
62
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
63
+ *
64
+ * @category Networking
65
+ * @package Net_DNS2
66
+ * @author Mike Pultz <mike@mikepultz.com>
67
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
68
+ * @link http://pear.php.net/package/Net_DNS2
69
+ * @see Net_DNS2_RR
70
+ *
71
+ */
72
+ class Net_DNS2_RR_CSYNC extends Net_DNS2_RR
73
+ {
74
+ /*
75
+ * serial number
76
+ */
77
+ public $serial;
78
+
79
+ /*
80
+ * flags
81
+ */
82
+ public $flags;
83
+
84
+ /*
85
+ * array of RR type names
86
+ */
87
+ public $type_bit_maps = array();
88
+
89
+ /**
90
+ * method to return the rdata portion of the packet as a string
91
+ *
92
+ * @return string
93
+ * @access protected
94
+ *
95
+ */
96
+ protected function rrToString()
97
+ {
98
+ $out = $this->serial . ' ' . $this->flags;
99
+
100
+ //
101
+ // show the RR's
102
+ //
103
+ foreach ($this->type_bit_maps as $rr) {
104
+
105
+ $out .= ' ' . strtoupper($rr);
106
+ }
107
+
108
+ return $out;
109
+ }
110
+
111
+ /**
112
+ * parses the rdata portion from a standard DNS config line
113
+ *
114
+ * @param array $rdata a string split line of values for the rdata
115
+ *
116
+ * @return boolean
117
+ * @access protected
118
+ *
119
+ */
120
+ protected function rrFromString(array $rdata)
121
+ {
122
+ $this->serial = array_shift($rdata);
123
+ $this->flags = array_shift($rdata);
124
+
125
+ $this->type_bit_maps = $rdata;
126
+
127
+ return true;
128
+ }
129
+
130
+ /**
131
+ * parses the rdata of the Net_DNS2_Packet object
132
+ *
133
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
134
+ *
135
+ * @return boolean
136
+ * @access protected
137
+ *
138
+ */
139
+ protected function rrSet(Net_DNS2_Packet &$packet)
140
+ {
141
+ if ($this->rdlength > 0) {
142
+
143
+ //
144
+ // unpack the serial and flags values
145
+ //
146
+ $x = unpack('@' . $packet->offset . '/Nserial/nflags', $packet->rdata);
147
+
148
+ $this->serial = Net_DNS2::expandUint32($x['serial']);
149
+ $this->flags = $x['flags'];
150
+
151
+ //
152
+ // parse out the RR bitmap
153
+ //
154
+ $this->type_bit_maps = Net_DNS2_BitMap::bitMapToArray(
155
+ substr($this->rdata, 6)
156
+ );
157
+
158
+ return true;
159
+ }
160
+
161
+ return false;
162
+ }
163
+
164
+ /**
165
+ * returns the rdata portion of the DNS packet
166
+ *
167
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
168
+ * compressed names
169
+ *
170
+ * @return mixed either returns a binary packed
171
+ * string or null on failure
172
+ * @access protected
173
+ *
174
+ */
175
+ protected function rrGet(Net_DNS2_Packet &$packet)
176
+ {
177
+ //
178
+ // pack the serial and flags values
179
+ //
180
+ $data = pack('Nn', $this->serial, $this->flags);
181
+
182
+ //
183
+ // convert the array of RR names to a type bitmap
184
+ //
185
+ $data .= Net_DNS2_BitMap::arrayToBitMap($this->type_bit_maps);
186
+
187
+ //
188
+ // advance the offset
189
+ //
190
+ $packet->offset += strlen($data);
191
+
192
+ return $data;
193
+ }
194
+ }
195
+
196
+ /*
197
+ * Local variables:
198
+ * tab-width: 4
199
+ * c-basic-offset: 4
200
+ * c-hanging-comment-ender-p: nil
201
+ * End:
202
+ */
203
+ ?>
includes/Net/DNS2/RR/DHCID.php ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * DHCID Resource Record - RFC4701 section 3.1
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | ID Type Code |
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * | Digest Type | /
59
+ * +--+--+--+--+--+--+--+--+ /
60
+ * / /
61
+ * / Digest /
62
+ * / /
63
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
64
+ *
65
+ * @category Networking
66
+ * @package Net_DNS2
67
+ * @author Mike Pultz <mike@mikepultz.com>
68
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
69
+ * @link http://pear.php.net/package/Net_DNS2
70
+ * @see Net_DNS2_RR
71
+ *
72
+ */
73
+ class Net_DNS2_RR_DHCID extends Net_DNS2_RR
74
+ {
75
+ /*
76
+ * Identifier type
77
+ */
78
+ public $id_type;
79
+
80
+ /*
81
+ * Digest Type
82
+ */
83
+ public $digest_type;
84
+
85
+ /*
86
+ * The digest
87
+ */
88
+ public $digest;
89
+
90
+
91
+ /**
92
+ * method to return the rdata portion of the packet as a string
93
+ *
94
+ * @return string
95
+ * @access protected
96
+ *
97
+ */
98
+ protected function rrToString()
99
+ {
100
+ $out = pack('nC', $this->id_type, $this->digest_type);
101
+ $out .= base64_decode($this->digest);
102
+
103
+ return base64_encode($out);
104
+ }
105
+
106
+ /**
107
+ * parses the rdata portion from a standard DNS config line
108
+ *
109
+ * @param array $rdata a string split line of values for the rdata
110
+ *
111
+ * @return boolean
112
+ * @access protected
113
+ *
114
+ */
115
+ protected function rrFromString(array $rdata)
116
+ {
117
+ $data = base64_decode(array_shift($rdata));
118
+ if (strlen($data) > 0) {
119
+
120
+ //
121
+ // unpack the id type and digest type
122
+ //
123
+ $x = unpack('nid_type/Cdigest_type', $data);
124
+
125
+ $this->id_type = $x['id_type'];
126
+ $this->digest_type = $x['digest_type'];
127
+
128
+ //
129
+ // copy out the digest
130
+ //
131
+ $this->digest = base64_encode(substr($data, 3, strlen($data) - 3));
132
+
133
+ return true;
134
+ }
135
+
136
+ return false;
137
+ }
138
+
139
+ /**
140
+ * parses the rdata of the Net_DNS2_Packet object
141
+ *
142
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
143
+ *
144
+ * @return boolean
145
+ * @access protected
146
+ *
147
+ */
148
+ protected function rrSet(Net_DNS2_Packet &$packet)
149
+ {
150
+ if ($this->rdlength > 0) {
151
+
152
+ //
153
+ // unpack the id type and digest type
154
+ //
155
+ $x = unpack('nid_type/Cdigest_type', $this->rdata);
156
+
157
+ $this->id_type = $x['id_type'];
158
+ $this->digest_type = $x['digest_type'];
159
+
160
+ //
161
+ // copy out the digest
162
+ //
163
+ $this->digest = base64_encode(
164
+ substr($this->rdata, 3, $this->rdlength - 3)
165
+ );
166
+
167
+ return true;
168
+ }
169
+
170
+ return false;
171
+ }
172
+
173
+ /**
174
+ * returns the rdata portion of the DNS packet
175
+ *
176
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
177
+ * compressed names
178
+ *
179
+ * @return mixed either returns a binary packed
180
+ * string or null on failure
181
+ * @access protected
182
+ *
183
+ */
184
+ protected function rrGet(Net_DNS2_Packet &$packet)
185
+ {
186
+ if (strlen($this->digest) > 0) {
187
+
188
+ $data = pack('nC', $this->id_type, $this->digest_type) .
189
+ base64_decode($this->digest);
190
+
191
+ $packet->offset += strlen($data);
192
+
193
+ return $data;
194
+ }
195
+
196
+ return null;
197
+ }
198
+ }
199
+
200
+ /*
201
+ * Local variables:
202
+ * tab-width: 4
203
+ * c-basic-offset: 4
204
+ * c-hanging-comment-ender-p: nil
205
+ * End:
206
+ */
207
+ ?>
includes/Net/DNS2/RR/DLV.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * The DLV RR is implemented exactly like the DS RR; so we just extend that
54
+ * class, and use all of it's methods
55
+ *
56
+ * @category Networking
57
+ * @package Net_DNS2
58
+ * @author Mike Pultz <mike@mikepultz.com>
59
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
60
+ * @link http://pear.php.net/package/Net_DNS2
61
+ * @see Net_DNS2_RR
62
+ *
63
+ */
64
+ class Net_DNS2_RR_DLV extends Net_DNS2_RR_DS
65
+ {
66
+ }
67
+
68
+ /*
69
+ * Local variables:
70
+ * tab-width: 4
71
+ * c-basic-offset: 4
72
+ * c-hanging-comment-ender-p: nil
73
+ * End:
74
+ */
75
+ ?>
includes/Net/DNS2/RR/DNAME.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * DNAME Resource Record - RFC2672 section 3
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * / DNAME /
57
+ * / /
58
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
59
+ *
60
+ * @category Networking
61
+ * @package Net_DNS2
62
+ * @author Mike Pultz <mike@mikepultz.com>
63
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
64
+ * @link http://pear.php.net/package/Net_DNS2
65
+ * @see Net_DNS2_RR
66
+ *
67
+ */
68
+ class Net_DNS2_RR_DNAME extends Net_DNS2_RR
69
+ {
70
+ /*
71
+ * The target name
72
+ */
73
+ public $dname;
74
+
75
+ /**
76
+ * method to return the rdata portion of the packet as a string
77
+ *
78
+ * @return string
79
+ * @access protected
80
+ *
81
+ */
82
+ protected function rrToString()
83
+ {
84
+ return $this->cleanString($this->dname) . '.';
85
+ }
86
+
87
+ /**
88
+ * parses the rdata portion from a standard DNS config line
89
+ *
90
+ * @param array $rdata a string split line of values for the rdata
91
+ *
92
+ * @return boolean
93
+ * @access protected
94
+ *
95
+ */
96
+ protected function rrFromString(array $rdata)
97
+ {
98
+ $this->dname = $this->cleanString(array_shift($rdata));
99
+ return true;
100
+ }
101
+
102
+ /**
103
+ * parses the rdata of the Net_DNS2_Packet object
104
+ *
105
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
106
+ *
107
+ * @return boolean
108
+ * @access protected
109
+ *
110
+ */
111
+ protected function rrSet(Net_DNS2_Packet &$packet)
112
+ {
113
+ if ($this->rdlength > 0) {
114
+
115
+ $offset = $packet->offset;
116
+ $this->dname = Net_DNS2_Packet::expand($packet, $offset);
117
+
118
+ return true;
119
+ }
120
+
121
+ return false;
122
+ }
123
+
124
+ /**
125
+ * returns the rdata portion of the DNS packet
126
+ *
127
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
128
+ * compressed names
129
+ *
130
+ * @return mixed either returns a binary packed
131
+ * string or null on failure
132
+ * @access protected
133
+ *
134
+ */
135
+ protected function rrGet(Net_DNS2_Packet &$packet)
136
+ {
137
+ if (strlen($this->dname) > 0) {
138
+
139
+ return $packet->compress($this->dname, $packet->offset);
140
+ }
141
+
142
+ return null;
143
+ }
144
+ }
145
+
146
+ /*
147
+ * Local variables:
148
+ * tab-width: 4
149
+ * c-basic-offset: 4
150
+ * c-hanging-comment-ender-p: nil
151
+ * End:
152
+ */
153
+ ?>
includes/Net/DNS2/RR/DNSKEY.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * DNSKEY Resource Record - RFC4034 sction 2.1
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | Flags | Protocol | Algorithm |
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59
+ * / /
60
+ * / Public Key /
61
+ * / /
62
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
+ *
64
+ * @category Networking
65
+ * @package Net_DNS2
66
+ * @author Mike Pultz <mike@mikepultz.com>
67
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
68
+ * @link http://pear.php.net/package/Net_DNS2
69
+ * @see Net_DNS2_RR
70
+ *
71
+ */
72
+ class Net_DNS2_RR_DNSKEY extends Net_DNS2_RR
73
+ {
74
+ /*
75
+ * flags
76
+ */
77
+ public $flags;
78
+
79
+ /*
80
+ * protocol
81
+ */
82
+ public $protocol;
83
+
84
+ /*
85
+ * algorithm used
86
+ */
87
+ public $algorithm;
88
+
89
+ /*
90
+ * the public key
91
+ */
92
+ public $key;
93
+
94
+ /**
95
+ * method to return the rdata portion of the packet as a string
96
+ *
97
+ * @return string
98
+ * @access protected
99
+ *
100
+ */
101
+ protected function rrToString()
102
+ {
103
+ return $this->flags . ' ' . $this->protocol . ' ' .
104
+ $this->algorithm . ' ' . $this->key;
105
+ }
106
+
107
+ /**
108
+ * parses the rdata portion from a standard DNS config line
109
+ *
110
+ * @param array $rdata a string split line of values for the rdata
111
+ *
112
+ * @return boolean
113
+ * @access protected
114
+ *
115
+ */
116
+ protected function rrFromString(array $rdata)
117
+ {
118
+ $this->flags = array_shift($rdata);
119
+ $this->protocol = array_shift($rdata);
120
+ $this->algorithm = array_shift($rdata);
121
+ $this->key = implode(' ', $rdata);
122
+
123
+ return true;
124
+ }
125
+
126
+ /**
127
+ * parses the rdata of the Net_DNS2_Packet object
128
+ *
129
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
130
+ *
131
+ * @return boolean
132
+ * @access protected
133
+ *
134
+ */
135
+ protected function rrSet(Net_DNS2_Packet &$packet)
136
+ {
137
+ if ($this->rdlength > 0) {
138
+
139
+ //
140
+ // unpack the flags, protocol and algorithm
141
+ //
142
+ $x = unpack('nflags/Cprotocol/Calgorithm', $this->rdata);
143
+
144
+ //
145
+ // TODO: right now we're just displaying what's in DNS; we really
146
+ // should be parsing bit 7 and bit 15 of the flags field, and store
147
+ // those separately.
148
+ //
149
+ // right now the DNSSEC implementation is really just for display,
150
+ // we don't validate or handle any of the keys
151
+ //
152
+ $this->flags = $x['flags'];
153
+ $this->protocol = $x['protocol'];
154
+ $this->algorithm = $x['algorithm'];
155
+
156
+ $this->key = base64_encode(substr($this->rdata, 4));
157
+
158
+ return true;
159
+ }
160
+
161
+ return false;
162
+ }
163
+
164
+ /**
165
+ * returns the rdata portion of the DNS packet
166
+ *
167
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
168
+ * compressed names
169
+ *
170
+ * @return mixed either returns a binary packed
171
+ * string or null on failure
172
+ * @access protected
173
+ *
174
+ */
175
+ protected function rrGet(Net_DNS2_Packet &$packet)
176
+ {
177
+ if (strlen($this->key) > 0) {
178
+
179
+ $data = pack('nCC', $this->flags, $this->protocol, $this->algorithm);
180
+ $data .= base64_decode($this->key);
181
+
182
+ $packet->offset += strlen($data);
183
+
184
+ return $data;
185
+ }
186
+
187
+ return null;
188
+ }
189
+ }
190
+
191
+ /*
192
+ * Local variables:
193
+ * tab-width: 4
194
+ * c-basic-offset: 4
195
+ * c-hanging-comment-ender-p: nil
196
+ * End:
197
+ */
198
+ ?>
includes/Net/DNS2/RR/DS.php ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * DS Resource Record - RFC4034 sction 5.1
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | Key Tag | Algorithm | Digest Type |
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59
+ * / /
60
+ * / Digest /
61
+ * / /
62
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
+ *
64
+ * @category Networking
65
+ * @package Net_DNS2
66
+ * @author Mike Pultz <mike@mikepultz.com>
67
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
68
+ * @link http://pear.php.net/package/Net_DNS2
69
+ * @see Net_DNS2_RR
70
+ *
71
+ */
72
+ class Net_DNS2_RR_DS extends Net_DNS2_RR
73
+ {
74
+ /*
75
+ * key tag
76
+ */
77
+ public $keytag;
78
+
79
+ /*
80
+ * algorithm number
81
+ */
82
+ public $algorithm;
83
+
84
+ /*
85
+ * algorithm used to construct the digest
86
+ */
87
+ public $digesttype;
88
+
89
+ /*
90
+ * the digest data
91
+ */
92
+ public $digest;
93
+
94
+ /**
95
+ * method to return the rdata portion of the packet as a string
96
+ *
97
+ * @return string
98
+ * @access protected
99
+ *
100
+ */
101
+ protected function rrToString()
102
+ {
103
+ return $this->keytag . ' ' . $this->algorithm . ' ' .
104
+ $this->digesttype . ' ' . $this->digest;
105
+ }
106
+
107
+ /**
108
+ * parses the rdata portion from a standard DNS config line
109
+ *
110
+ * @param array $rdata a string split line of values for the rdata
111
+ *
112
+ * @return boolean
113
+ * @access protected
114
+ *
115
+ */
116
+ protected function rrFromString(array $rdata)
117
+ {
118
+ $this->keytag = array_shift($rdata);
119
+ $this->algorithm = array_shift($rdata);
120
+ $this->digesttype = array_shift($rdata);
121
+ $this->digest = implode('', $rdata);
122
+
123
+ return true;
124
+ }
125
+
126
+ /**
127
+ * parses the rdata of the Net_DNS2_Packet object
128
+ *
129
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
130
+ *
131
+ * @return boolean
132
+ * @access protected
133
+ *
134
+ */
135
+ protected function rrSet(Net_DNS2_Packet &$packet)
136
+ {
137
+ if ($this->rdlength > 0) {
138
+
139
+ //
140
+ // unpack the keytag, algorithm and digesttype
141
+ //
142
+ $x = unpack('nkeytag/Calgorithm/Cdigesttype', $this->rdata);
143
+
144
+ $this->keytag = $x['keytag'];
145
+ $this->algorithm = $x['algorithm'];
146
+ $this->digesttype = $x['digesttype'];
147
+
148
+ //
149
+ // figure out the digest size
150
+ //
151
+ $digest_size = 0;
152
+ if ($this->digesttype == 1) {
153
+
154
+ $digest_size = 20; // SHA1
155
+
156
+ } else if ($this->digesttype == 2) {
157
+
158
+ $digest_size = 32; // SHA256
159
+ }
160
+
161
+ //
162
+ // copy the digest
163
+ //
164
+ $x = unpack('H*', substr($this->rdata, 4, $digest_size));
165
+ $this->digest = $x[1];
166
+
167
+ return true;
168
+ }
169
+
170
+ return false;
171
+ }
172
+
173
+ /**
174
+ * returns the rdata portion of the DNS packet
175
+ *
176
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
177
+ * compressed names
178
+ *
179
+ * @return mixed either returns a binary packed
180
+ * string or null on failure
181
+ * @access protected
182
+ *
183
+ */
184
+ protected function rrGet(Net_DNS2_Packet &$packet)
185
+ {
186
+ if (strlen($this->digest) > 0) {
187
+
188
+ $data = pack(
189
+ 'nCCH*',
190
+ $this->keytag, $this->algorithm, $this->digesttype, $this->digest
191
+ );
192
+
193
+ $packet->offset += strlen($data);
194
+
195
+ return $data;
196
+ }
197
+
198
+ return null;
199
+ }
200
+ }
201
+
202
+ /*
203
+ * Local variables:
204
+ * tab-width: 4
205
+ * c-basic-offset: 4
206
+ * c-hanging-comment-ender-p: nil
207
+ * End:
208
+ */
209
+ ?>
includes/Net/DNS2/RR/EID.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * EID Resource Record - undefined; the rdata is simply used as-is in it's
54
+ * binary format, so not process has to be done.
55
+ *
56
+ * @category Networking
57
+ * @package Net_DNS2
58
+ * @author Mike Pultz <mike@mikepultz.com>
59
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
60
+ * @link http://pear.php.net/package/Net_DNS2
61
+ * @see Net_DNS2_RR
62
+ *
63
+ */
64
+ class Net_DNS2_RR_EID extends Net_DNS2_RR
65
+ {
66
+ /**
67
+ * method to return the rdata portion of the packet as a string
68
+ *
69
+ * @return string
70
+ * @access protected
71
+ *
72
+ */
73
+ protected function rrToString()
74
+ {
75
+ return '';
76
+ }
77
+
78
+ /**
79
+ * parses the rdata portion from a standard DNS config line
80
+ *
81
+ * @param array $rdata a string split line of values for the rdata
82
+ *
83
+ * @return boolean
84
+ * @access protected
85
+ *
86
+ */
87
+ protected function rrFromString(array $rdata)
88
+ {
89
+ return true;
90
+ }
91
+
92
+ /**
93
+ * parses the rdata of the Net_DNS2_Packet object
94
+ *
95
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
96
+ *
97
+ * @return boolean
98
+ * @access protected
99
+ *
100
+ */
101
+ protected function rrSet(Net_DNS2_Packet &$packet)
102
+ {
103
+ return true;
104
+ }
105
+
106
+ /**
107
+ * returns the rdata portion of the DNS packet
108
+ *
109
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
110
+ * compressed names
111
+ *
112
+ * @return mixed either returns a binary packed
113
+ * string or null on failure
114
+ * @access protected
115
+ *
116
+ */
117
+ protected function rrGet(Net_DNS2_Packet &$packet)
118
+ {
119
+ return $this->rdata;
120
+ }
121
+ }
122
+
123
+ /*
124
+ * Local variables:
125
+ * tab-width: 4
126
+ * c-basic-offset: 4
127
+ * c-hanging-comment-ender-p: nil
128
+ * End:
129
+ */
130
+ ?>
includes/Net/DNS2/RR/EUI48.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2013, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2013 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.3.2
49
+ *
50
+ */
51
+
52
+ /**
53
+ * EUI48 Resource Record - RFC7043 section 3.1
54
+ *
55
+ * 0 1 2 3
56
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
57
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58
+ * | EUI-48 Address |
59
+ * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60
+ * | |
61
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62
+ *
63
+ * @category Networking
64
+ * @package Net_DNS2
65
+ * @author Mike Pultz <mike@mikepultz.com>
66
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
67
+ * @link http://pear.php.net/package/Net_DNS2
68
+ * @see Net_DNS2_RR
69
+ *
70
+ */
71
+ class Net_DNS2_RR_EUI48 extends Net_DNS2_RR
72
+ {
73
+ /*
74
+ * The EUI48 address, in hex format
75
+ */
76
+ public $address;
77
+
78
+ /**
79
+ * method to return the rdata portion of the packet as a string
80
+ *
81
+ * @return string
82
+ * @access protected
83
+ *
84
+ */
85
+ protected function rrToString()
86
+ {
87
+ return $this->address;
88
+ }
89
+
90
+ /**
91
+ * parses the rdata portion from a standard DNS config line
92
+ *
93
+ * @param array $rdata a string split line of values for the rdata
94
+ *
95
+ * @return boolean
96
+ * @access protected
97
+ *
98
+ */
99
+ protected function rrFromString(array $rdata)
100
+ {
101
+ $value = array_shift($rdata);
102
+
103
+ //
104
+ // re: RFC 7043, the field must be represented as six two-digit hex numbers
105
+ // separated by hyphens.
106
+ //
107
+ $a = explode('-', $value);
108
+ if (count($a) != 6) {
109
+
110
+ return false;
111
+ }
112
+
113
+ //
114
+ // make sure they're all hex values
115
+ //
116
+ foreach ($a as $i) {
117
+ if (ctype_xdigit($i) == false) {
118
+ return false;
119
+ }
120
+ }
121
+
122
+ //
123
+ // store it
124
+ //
125
+ $this->address = strtolower($value);
126
+
127
+ return true;
128
+ }
129
+
130
+ /**
131
+ * parses the rdata of the Net_DNS2_Packet object
132
+ *
133
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
134
+ *
135
+ * @return boolean
136
+ * @access protected
137
+ *
138
+ */
139
+ protected function rrSet(Net_DNS2_Packet &$packet)
140
+ {
141
+ if ($this->rdlength > 0) {
142
+
143
+ $x = unpack('C6', $this->rdata);
144
+ if (count($x) == 6) {
145
+
146
+ $this->address = vsprintf('%02x-%02x-%02x-%02x-%02x-%02x', $x);
147
+ return true;
148
+ }
149
+ }
150
+
151
+ return false;
152
+ }
153
+
154
+ /**
155
+ * returns the rdata portion of the DNS packet
156
+ *
157
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
158
+ * compressed names
159
+ *
160
+ * @return mixed either returns a binary packed
161
+ * string or null on failure
162
+ * @access protected
163
+ *
164
+ */
165
+ protected function rrGet(Net_DNS2_Packet &$packet)
166
+ {
167
+ $data = '';
168
+
169
+ $a = explode('-', $this->address);
170
+ foreach ($a as $b) {
171
+
172
+ $data .= chr(hexdec($b));
173
+ }
174
+
175
+ $packet->offset += 6;
176
+ return $data;
177
+ }
178
+ }
179
+
180
+ /*
181
+ * Local variables:
182
+ * tab-width: 4
183
+ * c-basic-offset: 4
184
+ * c-hanging-comment-ender-p: nil
185
+ * End:
186
+ */
187
+ ?>
includes/Net/DNS2/RR/EUI64.php ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2013, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2013 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.3.2
49
+ *
50
+ */
51
+
52
+ /**
53
+ * EUI64 Resource Record - RFC7043 section 4.1
54
+ *
55
+ * 0 1 2 3
56
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
57
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58
+ * | EUI-48 Address |
59
+ * | |
60
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
+ *
62
+ * @category Networking
63
+ * @package Net_DNS2
64
+ * @author Mike Pultz <mike@mikepultz.com>
65
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
66
+ * @link http://pear.php.net/package/Net_DNS2
67
+ * @see Net_DNS2_RR
68
+ *
69
+ */
70
+ class Net_DNS2_RR_EUI64 extends Net_DNS2_RR
71
+ {
72
+ /*
73
+ * The EUI64 address, in hex format
74
+ */
75
+ public $address;
76
+
77
+ /**
78
+ * method to return the rdata portion of the packet as a string
79
+ *
80
+ * @return string
81
+ * @access protected
82
+ *
83
+ */
84
+ protected function rrToString()
85
+ {
86
+ return $this->address;
87
+ }
88
+
89
+ /**
90
+ * parses the rdata portion from a standard DNS config line
91
+ *
92
+ * @param array $rdata a string split line of values for the rdata
93
+ *
94
+ * @return boolean
95
+ * @access protected
96
+ *
97
+ */
98
+ protected function rrFromString(array $rdata)
99
+ {
100
+ $value = array_shift($rdata);
101
+
102
+ //
103
+ // re: RFC 7043, the field must be represented as 8 two-digit hex numbers
104
+ // separated by hyphens.
105
+ //
106
+ $a = explode('-', $value);
107
+ if (count($a) != 8) {
108
+
109
+ return false;
110
+ }
111
+
112
+ //
113
+ // make sure they're all hex values
114
+ //
115
+ foreach ($a as $i) {
116
+ if (ctype_xdigit($i) == false) {
117
+ return false;
118
+ }
119
+ }
120
+
121
+ //
122
+ // store it
123
+ //
124
+ $this->address = strtolower($value);
125
+
126
+ return true;
127
+ }
128
+
129
+ /**
130
+ * parses the rdata of the Net_DNS2_Packet object
131
+ *
132
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
133
+ *
134
+ * @return boolean
135
+ * @access protected
136
+ *
137
+ */
138
+ protected function rrSet(Net_DNS2_Packet &$packet)
139
+ {
140
+ if ($this->rdlength > 0) {
141
+
142
+ $x = unpack('C8', $this->rdata);
143
+ if (count($x) == 8) {
144
+
145
+ $this->address = vsprintf(
146
+ '%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x', $x
147
+ );
148
+ return true;
149
+ }
150
+ }
151
+
152
+ return false;
153
+ }
154
+
155
+ /**
156
+ * returns the rdata portion of the DNS packet
157
+ *
158
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
159
+ * compressed names
160
+ *
161
+ * @return mixed either returns a binary packed
162
+ * string or null on failure
163
+ * @access protected
164
+ *
165
+ */
166
+ protected function rrGet(Net_DNS2_Packet &$packet)
167
+ {
168
+ $data = '';
169
+
170
+ $a = explode('-', $this->address);
171
+ foreach ($a as $b) {
172
+
173
+ $data .= chr(hexdec($b));
174
+ }
175
+
176
+ $packet->offset += 8;
177
+ return $data;
178
+ }
179
+ }
180
+
181
+ /*
182
+ * Local variables:
183
+ * tab-width: 4
184
+ * c-basic-offset: 4
185
+ * c-hanging-comment-ender-p: nil
186
+ * End:
187
+ */
188
+ ?>
includes/Net/DNS2/RR/HINFO.php ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * HINFO Resource Record - RFC1035 section 3.3.2
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * / CPU /
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * / OS /
59
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
60
+ *
61
+ * @category Networking
62
+ * @package Net_DNS2
63
+ * @author Mike Pultz <mike@mikepultz.com>
64
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
65
+ * @link http://pear.php.net/package/Net_DNS2
66
+ * @see Net_DNS2_RR
67
+ *
68
+ */
69
+ class Net_DNS2_RR_HINFO extends Net_DNS2_RR
70
+ {
71
+ /*
72
+ * computer informatino
73
+ */
74
+ public $cpu;
75
+
76
+ /*
77
+ * operataing system
78
+ */
79
+ public $os;
80
+
81
+ /**
82
+ * method to return the rdata portion of the packet as a string
83
+ *
84
+ * @return string
85
+ * @access protected
86
+ *
87
+ */
88
+ protected function rrToString()
89
+ {
90
+ return $this->formatString($this->cpu) . ' ' .
91
+ $this->formatString($this->os);
92
+ }
93
+
94
+ /**
95
+ * parses the rdata portion from a standard DNS config line
96
+ *
97
+ * @param array $rdata a string split line of values for the rdata
98
+ *
99
+ * @return boolean
100
+ * @access protected
101
+ *
102
+ */
103
+ protected function rrFromString(array $rdata)
104
+ {
105
+ $data = $this->buildString($rdata);
106
+ if (count($data) == 2) {
107
+
108
+ $this->cpu = $data[0];
109
+ $this->os = $data[1];
110
+
111
+ return true;
112
+ }
113
+
114
+ return false;
115
+ }
116
+
117
+ /**
118
+ * parses the rdata of the Net_DNS2_Packet object
119
+ *
120
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
121
+ *
122
+ * @return boolean
123
+ * @access protected
124
+ *
125
+ */
126
+ protected function rrSet(Net_DNS2_Packet &$packet)
127
+ {
128
+ if ($this->rdlength > 0) {
129
+
130
+ $offset = $packet->offset;
131
+
132
+ $this->cpu = trim(Net_DNS2_Packet::label($packet, $offset), '"');
133
+ $this->os = trim(Net_DNS2_Packet::label($packet, $offset), '"');
134
+
135
+ return true;
136
+ }
137
+
138
+ return false;
139
+ }
140
+
141
+ /**
142
+ * returns the rdata portion of the DNS packet
143
+ *
144
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
145
+ * compressed names
146
+ *
147
+ * @return mixed either returns a binary packed
148
+ * string or null on failure
149
+ * @access protected
150
+ *
151
+ */
152
+ protected function rrGet(Net_DNS2_Packet &$packet)
153
+ {
154
+ if (strlen($this->cpu) > 0) {
155
+
156
+ $data = chr(strlen($this->cpu)) . $this->cpu;
157
+ $data .= chr(strlen($this->os)) . $this->os;
158
+
159
+ $packet->offset += strlen($data);
160
+
161
+ return $data;
162
+ }
163
+
164
+ return null;
165
+ }
166
+ }
167
+
168
+ /*
169
+ * Local variables:
170
+ * tab-width: 4
171
+ * c-basic-offset: 4
172
+ * c-hanging-comment-ender-p: nil
173
+ * End:
174
+ */
175
+ ?>
includes/Net/DNS2/RR/HIP.php ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.0.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * HIP Resource Record - RFC5205 section 5
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | HIT length | PK algorithm | PK length |
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59
+ * | |
60
+ * ~ HIT ~
61
+ * | |
62
+ * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
+ * | | |
64
+ * +-+-+-+-+-+-+-+-+-+-+-+ +
65
+ * | Public Key |
66
+ * ~ ~
67
+ * | |
68
+ * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69
+ * | | |
70
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
71
+ * | |
72
+ * ~ Rendezvous Servers ~
73
+ * | |
74
+ * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75
+ * | |
76
+ * +-+-+-+-+-+-+-+
77
+ *
78
+ * @category Networking
79
+ * @package Net_DNS2
80
+ * @author Mike Pultz <mike@mikepultz.com>
81
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
82
+ * @link http://pear.php.net/package/Net_DNS2
83
+ * @see Net_DNS2_RR
84
+ *
85
+ */
86
+ class Net_DNS2_RR_HIP extends Net_DNS2_RR
87
+ {
88
+ /*
89
+ * The length of the HIT field
90
+ */
91
+ public $hit_length;
92
+
93
+ /*
94
+ * the public key cryptographic algorithm
95
+ */
96
+ public $pk_algorithm;
97
+
98
+ /*
99
+ * the length of the public key field
100
+ */
101
+ public $pk_length;
102
+
103
+ /*
104
+ * The HIT is stored as a binary value in network byte order.
105
+ */
106
+ public $hit;
107
+
108
+ /*
109
+ * The public key
110
+ */
111
+ public $public_key;
112
+
113
+ /*
114
+ * a list of rendezvous servers
115
+ */
116
+ public $rendezvous_servers = array();
117
+
118
+ /**
119
+ * method to return the rdata portion of the packet as a string
120
+ *
121
+ * @return string
122
+ * @access protected
123
+ *
124
+ */
125
+ protected function rrToString()
126
+ {
127
+ $out = $this->pk_algorithm . ' ' .
128
+ $this->hit . ' ' . $this->public_key . ' ';
129
+
130
+ foreach ($this->rendezvous_servers as $index => $server) {
131
+
132
+ $out .= $server . '. ';
133
+ }
134
+
135
+ return trim($out);
136
+ }
137
+
138
+ /**
139
+ * parses the rdata portion from a standard DNS config line
140
+ *
141
+ * @param array $rdata a string split line of values for the rdata
142
+ *
143
+ * @return boolean
144
+ * @access protected
145
+ *
146
+ */
147
+ protected function rrFromString(array $rdata)
148
+ {
149
+ $this->pk_algorithm = array_shift($rdata);
150
+ $this->hit = strtoupper(array_shift($rdata));
151
+ $this->public_key = array_shift($rdata);
152
+
153
+ //
154
+ // anything left on the array, must be one or more rendezevous servers. add
155
+ // them and strip off the trailing dot
156
+ //
157
+ if (count($rdata) > 0) {
158
+
159
+ $this->rendezvous_servers = preg_replace('/\.$/', '', $rdata);
160
+ }
161
+
162
+ //
163
+ // store the lengths;
164
+ //
165
+ $this->hit_length = strlen(pack('H*', $this->hit));
166
+ $this->pk_length = strlen(base64_decode($this->public_key));
167
+
168
+ return true;
169
+ }
170
+
171
+ /**
172
+ * parses the rdata of the Net_DNS2_Packet object
173
+ *
174
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
175
+ *
176
+ * @return boolean
177
+ * @access protected
178
+ *
179
+ */
180
+ protected function rrSet(Net_DNS2_Packet &$packet)
181
+ {
182
+ if ($this->rdlength > 0) {
183
+
184
+ //
185
+ // unpack the algorithm and length values
186
+ //
187
+ $x = unpack('Chit_length/Cpk_algorithm/npk_length', $this->rdata);
188
+
189
+ $this->hit_length = $x['hit_length'];
190
+ $this->pk_algorithm = $x['pk_algorithm'];
191
+ $this->pk_length = $x['pk_length'];
192
+
193
+ $offset = 4;
194
+
195
+ //
196
+ // copy out the HIT value
197
+ //
198
+ $hit = unpack('H*', substr($this->rdata, $offset, $this->hit_length));
199
+
200
+ $this->hit = strtoupper($hit[1]);
201
+ $offset += $this->hit_length;
202
+
203
+ //
204
+ // copy out the public key
205
+ //
206
+ $this->public_key = base64_encode(
207
+ substr($this->rdata, $offset, $this->pk_length)
208
+ );
209
+ $offset += $this->pk_length;
210
+
211
+ //
212
+ // copy out any possible rendezvous servers
213
+ //
214
+ $offset = $packet->offset + $offset;
215
+
216
+ while ( ($offset - $packet->offset) < $this->rdlength) {
217
+
218
+ $this->rendezvous_servers[] = Net_DNS2_Packet::expand(
219
+ $packet, $offset
220
+ );
221
+ }
222
+
223
+ return true;
224
+ }
225
+
226
+ return false;
227
+ }
228
+
229
+ /**
230
+ * returns the rdata portion of the DNS packet
231
+ *
232
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
233
+ * compressed names
234
+ *
235
+ * @return mixed either returns a binary packed
236
+ * string or null on failure
237
+ * @access protected
238
+ *
239
+ */
240
+ protected function rrGet(Net_DNS2_Packet &$packet)
241
+ {
242
+ if ( (strlen($this->hit) > 0) && (strlen($this->public_key) > 0) ) {
243
+
244
+ //
245
+ // pack the length, algorithm and HIT values
246
+ //
247
+ $data = pack(
248
+ 'CCnH*',
249
+ $this->hit_length,
250
+ $this->pk_algorithm,
251
+ $this->pk_length,
252
+ $this->hit
253
+ );
254
+
255
+ //
256
+ // add the public key
257
+ //
258
+ $data .= base64_decode($this->public_key);
259
+
260
+ //
261
+ // add the offset
262
+ //
263
+ $packet->offset += strlen($data);
264
+
265
+ //
266
+ // add each rendezvous server
267
+ //
268
+ foreach ($this->rendezvous_servers as $index => $server) {
269
+
270
+ $data .= $packet->compress($server, $packet->offset);
271
+ }
272
+
273
+ return $data;
274
+ }
275
+
276
+ return null;
277
+ }
278
+ }
279
+
280
+ /*
281
+ * Local variables:
282
+ * tab-width: 4
283
+ * c-basic-offset: 4
284
+ * c-hanging-comment-ender-p: nil
285
+ * End:
286
+ */
287
+ ?>
includes/Net/DNS2/RR/IPSECKEY.php ADDED
@@ -0,0 +1,386 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * IPSECKEY Resource Record - RFC4025 section 2.1
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | precedence | gateway type | algorithm | gateway |
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------+ +
59
+ * ~ gateway ~
60
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
+ * | /
62
+ * / public key /
63
+ * / /
64
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
65
+ *
66
+ * @category Networking
67
+ * @package Net_DNS2
68
+ * @author Mike Pultz <mike@mikepultz.com>
69
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
70
+ * @link http://pear.php.net/package/Net_DNS2
71
+ * @see Net_DNS2_RR
72
+ *
73
+ */
74
+ class Net_DNS2_RR_IPSECKEY extends Net_DNS2_RR
75
+ {
76
+ const GATEWAY_TYPE_NONE = 0;
77
+ const GATEWAY_TYPE_IPV4 = 1;
78
+ const GATEWAY_TYPE_IPV6 = 2;
79
+ const GATEWAY_TYPE_DOMAIN = 3;
80
+
81
+ const ALGORITHM_NONE = 0;
82
+ const ALGORITHM_DSA = 1;
83
+ const ALGORITHM_RSA = 2;
84
+
85
+ /*
86
+ * Precedence (used the same was as a preference field)
87
+ */
88
+ public $precedence;
89
+
90
+ /*
91
+ * Gateway type - specifies the format of the gataway information
92
+ * This can be either:
93
+ *
94
+ * 0 No Gateway
95
+ * 1 IPv4 address
96
+ * 2 IPV6 address
97
+ * 3 wire-encoded domain name (not compressed)
98
+ *
99
+ */
100
+ public $gateway_type;
101
+
102
+ /*
103
+ * The algorithm used
104
+ *
105
+ * This can be:
106
+ *
107
+ * 0 No key is present
108
+ * 1 DSA key is present
109
+ * 2 RSA key is present
110
+ *
111
+ */
112
+ public $algorithm;
113
+
114
+ /*
115
+ * The gatway information
116
+ */
117
+ public $gateway;
118
+
119
+ /*
120
+ * the public key
121
+ */
122
+ public $key;
123
+
124
+ /**
125
+ * method to return the rdata portion of the packet as a string
126
+ *
127
+ * @return string
128
+ * @access protected
129
+ *
130
+ */
131
+ protected function rrToString()
132
+ {
133
+ $out = $this->precedence . ' ' . $this->gateway_type . ' ' .
134
+ $this->algorithm . ' ';
135
+
136
+ switch($this->gateway_type) {
137
+ case self::GATEWAY_TYPE_NONE:
138
+ $out .= '. ';
139
+ break;
140
+
141
+ case self::GATEWAY_TYPE_IPV4:
142
+ case self::GATEWAY_TYPE_IPV6:
143
+ $out .= $this->gateway . ' ';
144
+ break;
145
+
146
+ case self::GATEWAY_TYPE_DOMAIN:
147
+ $out .= $this->gateway . '. ';
148
+ break;
149
+ }
150
+
151
+ $out .= $this->key;
152
+ return $out;
153
+ }
154
+
155
+ /**
156
+ * parses the rdata portion from a standard DNS config line
157
+ *
158
+ * @param array $rdata a string split line of values for the rdata
159
+ *
160
+ * @return boolean
161
+ * @access protected
162
+ *
163
+ */
164
+ protected function rrFromString(array $rdata)
165
+ {
166
+ //
167
+ // load the data
168
+ //
169
+ $precedence = array_shift($rdata);
170
+ $gateway_type = array_shift($rdata);
171
+ $algorithm = array_shift($rdata);
172
+ $gateway = strtolower(trim(array_shift($rdata)));
173
+ $key = array_shift($rdata);
174
+
175
+ //
176
+ // validate it
177
+ //
178
+ switch($gateway_type) {
179
+ case self::GATEWAY_TYPE_NONE:
180
+ $gateway = '';
181
+ break;
182
+
183
+ case self::GATEWAY_TYPE_IPV4:
184
+ if (Net_DNS2::isIPv4($gateway) == false) {
185
+ return false;
186
+ }
187
+ break;
188
+
189
+ case self::GATEWAY_TYPE_IPV6:
190
+ if (Net_DNS2::isIPv6($gateway) == false) {
191
+ return false;
192
+ }
193
+ break;
194
+
195
+ case self::GATEWAY_TYPE_DOMAIN:
196
+ ; // do nothing
197
+ break;
198
+
199
+ default:
200
+ return false;
201
+ }
202
+
203
+ //
204
+ // check the algorithm and key
205
+ //
206
+ switch($algorithm) {
207
+ case self::ALGORITHM_NONE:
208
+ $key = '';
209
+ break;
210
+
211
+ case self::ALGORITHM_DSA:
212
+ case self::ALGORITHM_RSA:
213
+ ; // do nothing
214
+ break;
215
+
216
+ default:
217
+ return false;
218
+ }
219
+
220
+ //
221
+ // store the values
222
+ //
223
+ $this->precedence = $precedence;
224
+ $this->gateway_type = $gateway_type;
225
+ $this->algorithm = $algorithm;
226
+ $this->gateway = $gateway;
227
+ $this->key = $key;
228
+
229
+ return true;
230
+ }
231
+
232
+ /**
233
+ * parses the rdata of the Net_DNS2_Packet object
234
+ *
235
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
236
+ *
237
+ * @return boolean
238
+ * @access protected
239
+ *
240
+ */
241
+ protected function rrSet(Net_DNS2_Packet &$packet)
242
+ {
243
+ if ($this->rdlength > 0) {
244
+
245
+ //
246
+ // parse off the precedence, gateway type and algorithm
247
+ //
248
+ $x = unpack('Cprecedence/Cgateway_type/Calgorithm', $this->rdata);
249
+
250
+ $this->precedence = $x['precedence'];
251
+ $this->gateway_type = $x['gateway_type'];
252
+ $this->algorithm = $x['algorithm'];
253
+
254
+ $offset = 3;
255
+
256
+ //
257
+ // extract the gatway based on the type
258
+ //
259
+ switch($this->gateway_type) {
260
+ case self::GATEWAY_TYPE_NONE:
261
+ $this->gateway = '';
262
+ break;
263
+
264
+ case self::GATEWAY_TYPE_IPV4:
265
+ $this->gateway = inet_ntop(substr($this->rdata, $offset, 4));
266
+ $offset += 4;
267
+ break;
268
+
269
+ case self::GATEWAY_TYPE_IPV6:
270
+ $ip = unpack('n8', substr($this->rdata, $offset, 16));
271
+ if (count($ip) == 8) {
272
+
273
+ $this->gateway = vsprintf('%x:%x:%x:%x:%x:%x:%x:%x', $ip);
274
+ $offset += 16;
275
+ } else {
276
+
277
+ return false;
278
+ }
279
+ break;
280
+
281
+ case self::GATEWAY_TYPE_DOMAIN:
282
+
283
+ $doffset = $offset + $packet->offset;
284
+ $this->gateway = Net_DNS2_Packet::expand($packet, $doffset);
285
+ $offset = ($doffset - $packet->offset);
286
+ break;
287
+
288
+ default:
289
+ return false;
290
+ }
291
+
292
+ //
293
+ // extract the key
294
+ //
295
+ switch($this->algorithm) {
296
+ case self::ALGORITHM_NONE:
297
+ $this->key = '';
298
+ break;
299
+
300
+ case self::ALGORITHM_DSA:
301
+ case self::ALGORITHM_RSA:
302
+ $this->key = base64_encode(substr($this->rdata, $offset));
303
+ break;
304
+
305
+ default:
306
+ return false;
307
+ }
308
+
309
+ return true;
310
+ }
311
+
312
+ return false;
313
+ }
314
+
315
+ /**
316
+ * returns the rdata portion of the DNS packet
317
+ *
318
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
319
+ * compressed names
320
+ *
321
+ * @return mixed either returns a binary packed
322
+ * string or null on failure
323
+ * @access protected
324
+ *
325
+ */
326
+ protected function rrGet(Net_DNS2_Packet &$packet)
327
+ {
328
+ //
329
+ // pack the precedence, gateway type and algorithm
330
+ //
331
+ $data = pack(
332
+ 'CCC', $this->precedence, $this->gateway_type, $this->algorithm
333
+ );
334
+
335
+ //
336
+ // add the gateway based on the type
337
+ //
338
+ switch($this->gateway_type) {
339
+ case self::GATEWAY_TYPE_NONE:
340
+ ; // add nothing
341
+ break;
342
+
343
+ case self::GATEWAY_TYPE_IPV4:
344
+ case self::GATEWAY_TYPE_IPV6:
345
+ $data .= inet_pton($this->gateway);
346
+ break;
347
+
348
+ case self::GATEWAY_TYPE_DOMAIN:
349
+ $data .= chr(strlen($this->gateway)) . $this->gateway;
350
+ break;
351
+
352
+ default:
353
+ return null;
354
+ }
355
+
356
+ //
357
+ // add the key if there's one specified
358
+ //
359
+ switch($this->algorithm) {
360
+ case self::ALGORITHM_NONE:
361
+ ; // add nothing
362
+ break;
363
+
364
+ case self::ALGORITHM_DSA:
365
+ case self::ALGORITHM_RSA:
366
+ $data .= base64_decode($this->key);
367
+ break;
368
+
369
+ default:
370
+ return null;
371
+ }
372
+
373
+ $packet->offset += strlen($data);
374
+
375
+ return $data;
376
+ }
377
+ }
378
+
379
+ /*
380
+ * Local variables:
381
+ * tab-width: 4
382
+ * c-basic-offset: 4
383
+ * c-hanging-comment-ender-p: nil
384
+ * End:
385
+ */
386
+ ?>
includes/Net/DNS2/RR/ISDN.php ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * ISDN Resource Record - RFC1183 section 3.2
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * / ISDN-address /
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * / SA /
59
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
60
+ *
61
+ * @category Networking
62
+ * @package Net_DNS2
63
+ * @author Mike Pultz <mike@mikepultz.com>
64
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
65
+ * @link http://pear.php.net/package/Net_DNS2
66
+ * @see Net_DNS2_RR
67
+ *
68
+ */
69
+ class Net_DNS2_RR_ISDN extends Net_DNS2_RR
70
+ {
71
+ /*
72
+ * ISDN Number
73
+ */
74
+ public $isdnaddress;
75
+
76
+ /*
77
+ * Sub-Address
78
+ */
79
+ public $sa;
80
+
81
+ /**
82
+ * method to return the rdata portion of the packet as a string
83
+ *
84
+ * @return string
85
+ * @access protected
86
+ *
87
+ */
88
+ protected function rrToString()
89
+ {
90
+ return $this->formatString($this->isdnaddress) . ' ' .
91
+ $this->formatString($this->sa);
92
+ }
93
+
94
+ /**
95
+ * parses the rdata portion from a standard DNS config line
96
+ *
97
+ * @param array $rdata a string split line of values for the rdata
98
+ *
99
+ * @return boolean
100
+ * @access protected
101
+ *
102
+ */
103
+ protected function rrFromString(array $rdata)
104
+ {
105
+ $data = $this->buildString($rdata);
106
+ if (count($data) >= 1) {
107
+
108
+ $this->isdnaddress = $data[0];
109
+ if (isset($data[1])) {
110
+
111
+ $this->sa = $data[1];
112
+ }
113
+
114
+ return true;
115
+ }
116
+
117
+ return false;
118
+ }
119
+
120
+ /**
121
+ * parses the rdata of the Net_DNS2_Packet object
122
+ *
123
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
124
+ *
125
+ * @return boolean
126
+ * @access protected
127
+ *
128
+ */
129
+ protected function rrSet(Net_DNS2_Packet &$packet)
130
+ {
131
+ if ($this->rdlength > 0) {
132
+
133
+ $this->isdnaddress = Net_DNS2_Packet::label($packet, $packet->offset);
134
+
135
+ //
136
+ // look for a SA (sub address) - it's optional
137
+ //
138
+ if ( (strlen($this->isdnaddress) + 1) < $this->rdlength) {
139
+
140
+ $this->sa = Net_DNS2_Packet::label($packet, $packet->offset);
141
+ } else {
142
+
143
+ $this->sa = '';
144
+ }
145
+
146
+ return true;
147
+ }
148
+
149
+ return false;
150
+ }
151
+
152
+ /**
153
+ * returns the rdata portion of the DNS packet
154
+ *
155
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
156
+ * compressed names
157
+ *
158
+ * @return mixed either returns a binary packed
159
+ * string or null on failure
160
+ * @access protected
161
+ *
162
+ */
163
+ protected function rrGet(Net_DNS2_Packet &$packet)
164
+ {
165
+ if (strlen($this->isdnaddress) > 0) {
166
+
167
+ $data = chr(strlen($this->isdnaddress)) . $this->isdnaddress;
168
+ if (!empty($this->sa)) {
169
+
170
+ $data .= chr(strlen($this->sa));
171
+ $data .= $this->sa;
172
+ }
173
+
174
+ $packet->offset += strlen($data);
175
+
176
+ return $data;
177
+ }
178
+
179
+ return null;
180
+ }
181
+ }
182
+
183
+ /*
184
+ * Local variables:
185
+ * tab-width: 4
186
+ * c-basic-offset: 4
187
+ * c-hanging-comment-ender-p: nil
188
+ * End:
189
+ */
190
+ ?>
includes/Net/DNS2/RR/KEY.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * the KEY RR is implemented the same as the DNSKEY RR, the only difference
54
+ * is how the flags data is parsed.
55
+ *
56
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
57
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
58
+ * | A/C | Z | XT| Z | Z | NAMTYP| Z | Z | Z | Z | SIG |
59
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
60
+ *
61
+ * DNSKEY only uses bits 7 and 15
62
+ *
63
+ * We're not doing anything with these flags right now, so duplicating the
64
+ * class like this is fine.
65
+ *
66
+ * @category Networking
67
+ * @package Net_DNS2
68
+ * @author Mike Pultz <mike@mikepultz.com>
69
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
70
+ * @link http://pear.php.net/package/Net_DNS2
71
+ * @see Net_DNS2_RR
72
+ *
73
+ */
74
+ class Net_DNS2_RR_KEY extends Net_DNS2_RR_DNSKEY
75
+ {
76
+ }
77
+
78
+ /*
79
+ * Local variables:
80
+ * tab-width: 4
81
+ * c-basic-offset: 4
82
+ * c-hanging-comment-ender-p: nil
83
+ * End:
84
+ */
85
+ ?>
includes/Net/DNS2/RR/KX.php ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * KX Resource Record - RFC2230 section 3.1
54
+ *
55
+ * This class is almost identical to MX, except that the the exchanger
56
+ * domain is not compressed, it's added as a label
57
+ *
58
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
59
+ * | PREFERENCE |
60
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
61
+ * / EXCHANGER /
62
+ * / /
63
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
64
+ *
65
+ * @category Networking
66
+ * @package Net_DNS2
67
+ * @author Mike Pultz <mike@mikepultz.com>
68
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
69
+ * @link http://pear.php.net/package/Net_DNS2
70
+ * @see Net_DNS2_RR
71
+ *
72
+ */
73
+ class Net_DNS2_RR_KX extends Net_DNS2_RR
74
+ {
75
+ /*
76
+ * the preference for this mail exchanger
77
+ */
78
+ public $preference;
79
+
80
+ /*
81
+ * the hostname of the mail exchanger
82
+ */
83
+ public $exchange;
84
+
85
+ /**
86
+ * method to return the rdata portion of the packet as a string
87
+ *
88
+ * @return string
89
+ * @access protected
90
+ *
91
+ */
92
+ protected function rrToString()
93
+ {
94
+ return $this->preference . ' ' . $this->cleanString($this->exchange) . '.';
95
+ }
96
+
97
+ /**
98
+ * parses the rdata portion from a standard DNS config line
99
+ *
100
+ * @param array $rdata a string split line of values for the rdata
101
+ *
102
+ * @return boolean
103
+ * @access protected
104
+ *
105
+ */
106
+ protected function rrFromString(array $rdata)
107
+ {
108
+ $this->preference = array_shift($rdata);
109
+ $this->exchange = $this->cleanString(array_shift($rdata));
110
+
111
+ return true;
112
+ }
113
+
114
+ /**
115
+ * parses the rdata of the Net_DNS2_Packet object
116
+ *
117
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
118
+ *
119
+ * @return boolean
120
+ * @access protected
121
+ *
122
+ */
123
+ protected function rrSet(Net_DNS2_Packet &$packet)
124
+ {
125
+ if ($this->rdlength > 0) {
126
+
127
+ //
128
+ // parse the preference
129
+ //
130
+ $x = unpack('npreference', $this->rdata);
131
+ $this->preference = $x['preference'];
132
+
133
+ //
134
+ // get the exchange entry server)
135
+ //
136
+ $offset = $packet->offset + 2;
137
+ $this->exchange = Net_DNS2_Packet::label($packet, $offset);
138
+
139
+ return true;
140
+ }
141
+
142
+ return false;
143
+ }
144
+
145
+ /**
146
+ * returns the rdata portion of the DNS packet
147
+ *
148
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
149
+ * compressed names
150
+ *
151
+ * @return mixed either returns a binary packed
152
+ * string or null on failure
153
+ * @access protected
154
+ *
155
+ */
156
+ protected function rrGet(Net_DNS2_Packet &$packet)
157
+ {
158
+ if (strlen($this->exchange) > 0) {
159
+
160
+ $data = pack('nC', $this->preference, strlen($this->exchange)) .
161
+ $this->exchange;
162
+
163
+ $packet->offset += strlen($data);
164
+
165
+ return $data;
166
+ }
167
+
168
+ return null;
169
+ }
170
+ }
171
+
172
+ /*
173
+ * Local variables:
174
+ * tab-width: 4
175
+ * c-basic-offset: 4
176
+ * c-hanging-comment-ender-p: nil
177
+ * End:
178
+ */
179
+ ?>
includes/Net/DNS2/RR/L32.php ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2013, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2013 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.3.1
49
+ *
50
+ */
51
+
52
+ /**
53
+ * L32 Resource Record - RFC6742 section 2.2
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | Preference | Locator32 (16 MSBs) |
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59
+ * | Locator32 (16 LSBs) |
60
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
+ *
62
+ * @category Networking
63
+ * @package Net_DNS2
64
+ * @author Mike Pultz <mike@mikepultz.com>
65
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
66
+ * @link http://pear.php.net/package/Net_DNS2
67
+ * @see Net_DNS2_RR
68
+ *
69
+ */
70
+ class Net_DNS2_RR_L32 extends Net_DNS2_RR
71
+ {
72
+ /*
73
+ * The preference
74
+ */
75
+ public $preference;
76
+
77
+ /*
78
+ * The locator32 field
79
+ */
80
+ public $locator32;
81
+
82
+ /**
83
+ * method to return the rdata portion of the packet as a string
84
+ *
85
+ * @return string
86
+ * @access protected
87
+ *
88
+ */
89
+ protected function rrToString()
90
+ {
91
+ return $this->preference . ' ' . $this->locator32;
92
+ }
93
+
94
+ /**
95
+ * parses the rdata portion from a standard DNS config line
96
+ *
97
+ * @param array $rdata a string split line of values for the rdata
98
+ *
99
+ * @return boolean
100
+ * @access protected
101
+ *
102
+ */
103
+ protected function rrFromString(array $rdata)
104
+ {
105
+ $this->preference = array_shift($rdata);
106
+ $this->locator32 = array_shift($rdata);
107
+
108
+ return true;
109
+ }
110
+
111
+ /**
112
+ * parses the rdata of the Net_DNS2_Packet object
113
+ *
114
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
115
+ *
116
+ * @return boolean
117
+ * @access protected
118
+ *
119
+ */
120
+ protected function rrSet(Net_DNS2_Packet &$packet)
121
+ {
122
+ if ($this->rdlength > 0) {
123
+
124
+ //
125
+ // unpack the values
126
+ //
127
+ $x = unpack('npreference/C4locator', $this->rdata);
128
+
129
+ $this->preference = $x['preference'];
130
+
131
+ //
132
+ // build the locator value
133
+ //
134
+ $this->locator32 = $x['locator1'] . '.' . $x['locator2'] . '.' .
135
+ $x['locator3'] . '.' . $x['locator4'];
136
+
137
+ return true;
138
+ }
139
+
140
+ return false;
141
+ }
142
+
143
+ /**
144
+ * returns the rdata portion of the DNS packet
145
+ *
146
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
147
+ * compressed names
148
+ *
149
+ * @return mixed either returns a binary packed
150
+ * string or null on failure
151
+ * @access protected
152
+ *
153
+ */
154
+ protected function rrGet(Net_DNS2_Packet &$packet)
155
+ {
156
+ if (strlen($this->locator32) > 0) {
157
+
158
+ //
159
+ // break out the locator value
160
+ //
161
+ $n = explode('.', $this->locator32);
162
+
163
+ //
164
+ // pack the data
165
+ //
166
+ return pack('nC4', $this->preference, $n[0], $n[1], $n[2], $n[3]);
167
+ }
168
+
169
+ return null;
170
+ }
171
+ }
172
+
173
+ /*
174
+ * Local variables:
175
+ * tab-width: 4
176
+ * c-basic-offset: 4
177
+ * c-hanging-comment-ender-p: nil
178
+ * End:
179
+ */
180
+ ?>
includes/Net/DNS2/RR/L64.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2013, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2013 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.3.1
49
+ *
50
+ */
51
+
52
+ /**
53
+ * L64 Resource Record - RFC6742 section 2.3
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | Preference | |
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
59
+ * | Locator64 |
60
+ * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
+ * | |
62
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
+ *
64
+ * @category Networking
65
+ * @package Net_DNS2
66
+ * @author Mike Pultz <mike@mikepultz.com>
67
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
68
+ * @link http://pear.php.net/package/Net_DNS2
69
+ * @see Net_DNS2_RR
70
+ *
71
+ */
72
+ class Net_DNS2_RR_L64 extends Net_DNS2_RR
73
+ {
74
+ /*
75
+ * The preference
76
+ */
77
+ public $preference;
78
+
79
+ /*
80
+ * The locator64 field
81
+ */
82
+ public $locator64;
83
+
84
+ /**
85
+ * method to return the rdata portion of the packet as a string
86
+ *
87
+ * @return string
88
+ * @access protected
89
+ *
90
+ */
91
+ protected function rrToString()
92
+ {
93
+ return $this->preference . ' ' . $this->locator64;
94
+ }
95
+
96
+ /**
97
+ * parses the rdata portion from a standard DNS config line
98
+ *
99
+ * @param array $rdata a string split line of values for the rdata
100
+ *
101
+ * @return boolean
102
+ * @access protected
103
+ *
104
+ */
105
+ protected function rrFromString(array $rdata)
106
+ {
107
+ $this->preference = array_shift($rdata);
108
+ $this->locator64 = array_shift($rdata);
109
+
110
+ return true;
111
+ }
112
+
113
+ /**
114
+ * parses the rdata of the Net_DNS2_Packet object
115
+ *
116
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
117
+ *
118
+ * @return boolean
119
+ * @access protected
120
+ *
121
+ */
122
+ protected function rrSet(Net_DNS2_Packet &$packet)
123
+ {
124
+ if ($this->rdlength > 0) {
125
+
126
+ //
127
+ // unpack the values
128
+ //
129
+ $x = unpack('npreference/n4locator', $this->rdata);
130
+
131
+ $this->preference = $x['preference'];
132
+
133
+ //
134
+ // build the locator64
135
+ //
136
+ $this->locator64 = dechex($x['locator1']) . ':' .
137
+ dechex($x['locator2']) . ':' .
138
+ dechex($x['locator3']) . ':' .
139
+ dechex($x['locator4']);
140
+
141
+ return true;
142
+ }
143
+
144
+ return false;
145
+ }
146
+
147
+ /**
148
+ * returns the rdata portion of the DNS packet
149
+ *
150
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
151
+ * compressed names
152
+ *
153
+ * @return mixed either returns a binary packed
154
+ * string or null on failure
155
+ * @access protected
156
+ *
157
+ */
158
+ protected function rrGet(Net_DNS2_Packet &$packet)
159
+ {
160
+ if (strlen($this->locator64) > 0) {
161
+
162
+ //
163
+ // break out the locator64
164
+ //
165
+ $n = explode(':', $this->locator64);
166
+
167
+ //
168
+ // pack the data
169
+ //
170
+ return pack(
171
+ 'n5', $this->preference, hexdec($n[0]), hexdec($n[1]),
172
+ hexdec($n[2]), hexdec($n[3])
173
+ );
174
+ }
175
+
176
+ return null;
177
+ }
178
+ }
179
+
180
+ /*
181
+ * Local variables:
182
+ * tab-width: 4
183
+ * c-basic-offset: 4
184
+ * c-hanging-comment-ender-p: nil
185
+ * End:
186
+ */
187
+ ?>
includes/Net/DNS2/RR/LOC.php ADDED
@@ -0,0 +1,440 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * LOC Resource Record - RFC1876 section 2
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | VERSION | SIZE |
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * | HORIZ PRE | VERT PRE |
59
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
60
+ * | LATITUDE |
61
+ * | |
62
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
63
+ * | LONGITUDE |
64
+ * | |
65
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
66
+ * | ALTITUDE |
67
+ * | |
68
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
69
+ *
70
+ * @category Networking
71
+ * @package Net_DNS2
72
+ * @author Mike Pultz <mike@mikepultz.com>
73
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
74
+ * @link http://pear.php.net/package/Net_DNS2
75
+ * @see Net_DNS2_RR
76
+ *
77
+ */
78
+ class Net_DNS2_RR_LOC extends Net_DNS2_RR
79
+ {
80
+ /*
81
+ * the LOC version- should only ever be 0
82
+ */
83
+ public $version;
84
+
85
+ /*
86
+ * The diameter of a sphere enclosing the described entity
87
+ */
88
+ public $size;
89
+
90
+ /*
91
+ * The horizontal precision of the data
92
+ */
93
+ public $horiz_pre;
94
+
95
+ /*
96
+ * The vertical precision of the data
97
+ */
98
+ public $vert_pre;
99
+
100
+ /*
101
+ * The latitude - stored in decimal degrees
102
+ */
103
+ public $latitude;
104
+
105
+ /*
106
+ * The longitude - stored in decimal degrees
107
+ */
108
+ public $longitude;
109
+
110
+ /*
111
+ * The altitude - stored in decimal
112
+ */
113
+ public $altitude;
114
+
115
+ /*
116
+ * used for quick power-of-ten lookups
117
+ */
118
+ private $_powerOfTen = array(1, 10, 100, 1000, 10000, 100000,
119
+ 1000000,10000000,100000000,1000000000);
120
+
121
+ /*
122
+ * some conversion values
123
+ */
124
+ const CONV_SEC = 1000;
125
+ const CONV_MIN = 60000;
126
+ const CONV_DEG = 3600000;
127
+
128
+ const REFERENCE_ALT = 10000000;
129
+ const REFERENCE_LATLON = 2147483648;
130
+
131
+ /**
132
+ * method to return the rdata portion of the packet as a string
133
+ *
134
+ * @return string
135
+ * @access protected
136
+ *
137
+ */
138
+ protected function rrToString()
139
+ {
140
+ if ($this->version == 0) {
141
+
142
+ return $this->_d2Dms($this->latitude, 'LAT') . ' ' .
143
+ $this->_d2Dms($this->longitude, 'LNG') . ' ' .
144
+ sprintf('%.2fm', $this->altitude) . ' ' .
145
+ sprintf('%.2fm', $this->size) . ' ' .
146
+ sprintf('%.2fm', $this->horiz_pre) . ' ' .
147
+ sprintf('%.2fm', $this->vert_pre);
148
+ }
149
+
150
+ return '';
151
+ }
152
+
153
+ /**
154
+ * parses the rdata portion from a standard DNS config line
155
+ *
156
+ * @param array $rdata a string split line of values for the rdata
157
+ *
158
+ * @return boolean
159
+ * @access protected
160
+ *
161
+ */
162
+ protected function rrFromString(array $rdata)
163
+ {
164
+ //
165
+ // format as defined by RFC1876 section 3
166
+ //
167
+ // d1 [m1 [s1]] {"N"|"S"} d2 [m2 [s2]] {"E"|"W"} alt["m"]
168
+ // [siz["m"] [hp["m"] [vp["m"]]]]
169
+ //
170
+ $res = preg_match(
171
+ '/^(\d+) \s+((\d+) \s+)?(([\d.]+) \s+)?(N|S) \s+(\d+) ' .
172
+ '\s+((\d+) \s+)?(([\d.]+) \s+)?(E|W) \s+(-?[\d.]+) m?(\s+ ' .
173
+ '([\d.]+) m?)?(\s+ ([\d.]+) m?)?(\s+ ([\d.]+) m?)?/ix',
174
+ implode(' ', $rdata), $x
175
+ );
176
+
177
+ if ($res) {
178
+
179
+ //
180
+ // latitude
181
+ //
182
+ $latdeg = $x[1];
183
+ $latmin = (isset($x[3])) ? $x[3] : 0;
184
+ $latsec = (isset($x[5])) ? $x[5] : 0;
185
+ $lathem = strtoupper($x[6]);
186
+
187
+ $this->latitude = $this->_dms2d($latdeg, $latmin, $latsec, $lathem);
188
+
189
+ //
190
+ // longitude
191
+ //
192
+ $londeg = $x[7];
193
+ $lonmin = (isset($x[9])) ? $x[9] : 0;
194
+ $lonsec = (isset($x[11])) ? $x[11] : 0;
195
+ $lonhem = strtoupper($x[12]);
196
+
197
+ $this->longitude = $this->_dms2d($londeg, $lonmin, $lonsec, $lonhem);
198
+
199
+ //
200
+ // the rest of teh values
201
+ //
202
+ $version = 0;
203
+
204
+ $this->size = (isset($x[15])) ? $x[15] : 1;
205
+ $this->horiz_pre = ((isset($x[17])) ? $x[17] : 10000);
206
+ $this->vert_pre = ((isset($x[19])) ? $x[19] : 10);
207
+ $this->altitude = $x[13];
208
+
209
+ return true;
210
+ }
211
+
212
+ return false;
213
+ }
214
+
215
+ /**
216
+ * parses the rdata of the Net_DNS2_Packet object
217
+ *
218
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
219
+ *
220
+ * @return boolean
221
+ * @access protected
222
+ *
223
+ */
224
+ protected function rrSet(Net_DNS2_Packet &$packet)
225
+ {
226
+ if ($this->rdlength > 0) {
227
+
228
+ //
229
+ // unpack all the values
230
+ //
231
+ $x = unpack(
232
+ 'Cver/Csize/Choriz_pre/Cvert_pre/Nlatitude/Nlongitude/Naltitude',
233
+ $this->rdata
234
+ );
235
+
236
+ //
237
+ // version must be 0 per RFC 1876 section 2
238
+ //
239
+ $this->version = $x['ver'];
240
+ if ($this->version == 0) {
241
+
242
+ $this->size = $this->_precsizeNtoA($x['size']);
243
+ $this->horiz_pre = $this->_precsizeNtoA($x['horiz_pre']);
244
+ $this->vert_pre = $this->_precsizeNtoA($x['vert_pre']);
245
+
246
+ //
247
+ // convert the latitude and longitude to degress in decimal
248
+ //
249
+ if ($x['latitude'] < 0) {
250
+
251
+ $this->latitude = ($x['latitude'] +
252
+ self::REFERENCE_LATLON) / self::CONV_DEG;
253
+ } else {
254
+
255
+ $this->latitude = ($x['latitude'] -
256
+ self::REFERENCE_LATLON) / self::CONV_DEG;
257
+ }
258
+
259
+ if ($x['longitude'] < 0) {
260
+
261
+ $this->longitude = ($x['longitude'] +
262
+ self::REFERENCE_LATLON) / self::CONV_DEG;
263
+ } else {
264
+
265
+ $this->longitude = ($x['longitude'] -
266
+ self::REFERENCE_LATLON) / self::CONV_DEG;
267
+ }
268
+
269
+ //
270
+ // convert down the altitude
271
+ //
272
+ $this->altitude = ($x['altitude'] - self::REFERENCE_ALT) / 100;
273
+
274
+ return true;
275
+
276
+ } else {
277
+
278
+ return false;
279
+ }
280
+
281
+ return true;
282
+ }
283
+
284
+ return false;
285
+ }
286
+
287
+ /**
288
+ * returns the rdata portion of the DNS packet
289
+ *
290
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
291
+ * compressed names
292
+ *
293
+ * @return mixed either returns a binary packed
294
+ * string or null on failure
295
+ * @access protected
296
+ *
297
+ */
298
+ protected function rrGet(Net_DNS2_Packet &$packet)
299
+ {
300
+ if ($this->version == 0) {
301
+
302
+ $lat = 0;
303
+ $lng = 0;
304
+
305
+ if ($this->latitude < 0) {
306
+
307
+ $lat = ($this->latitude * self::CONV_DEG) - self::REFERENCE_LATLON;
308
+ } else {
309
+
310
+ $lat = ($this->latitude * self::CONV_DEG) + self::REFERENCE_LATLON;
311
+ }
312
+
313
+ if ($this->longitude < 0) {
314
+
315
+ $lng = ($this->longitude * self::CONV_DEG) - self::REFERENCE_LATLON;
316
+ } else {
317
+
318
+ $lng = ($this->longitude * self::CONV_DEG) + self::REFERENCE_LATLON;
319
+ }
320
+
321
+ $packet->offset += 16;
322
+
323
+ return pack(
324
+ 'CCCCNNN',
325
+ $this->version,
326
+ $this->_precsizeAtoN($this->size),
327
+ $this->_precsizeAtoN($this->horiz_pre),
328
+ $this->_precsizeAtoN($this->vert_pre),
329
+ $lat, $lng,
330
+ ($this->altitude * 100) + self::REFERENCE_ALT
331
+ );
332
+ }
333
+
334
+ return null;
335
+ }
336
+
337
+ /**
338
+ * takes an XeY precision/size value, returns a string representation.
339
+ * shamlessly stolen from RFC1876 Appendix A
340
+ *
341
+ * @param integer $prec the value to convert
342
+ *
343
+ * @return string
344
+ * @access private
345
+ *
346
+ */
347
+ private function _precsizeNtoA($prec)
348
+ {
349
+ $mantissa = (($prec >> 4) & 0x0f) % 10;
350
+ $exponent = (($prec >> 0) & 0x0f) % 10;
351
+
352
+ return $mantissa * $this->_powerOfTen[$exponent];
353
+ }
354
+
355
+ /**
356
+ * converts ascii size/precision X * 10**Y(cm) to 0xXY.
357
+ * shamlessly stolen from RFC1876 Appendix A
358
+ *
359
+ * @param string $prec the value to convert
360
+ *
361
+ * @return integer
362
+ * @access private
363
+ *
364
+ */
365
+ private function _precsizeAtoN($prec)
366
+ {
367
+ $exponent = 0;
368
+ while ($prec >= 10) {
369
+
370
+ $prec /= 10;
371
+ ++$exponent;
372
+ }
373
+
374
+ return ($prec << 4) | ($exponent & 0x0f);
375
+ }
376
+
377
+ /**
378
+ * convert lat/lng in deg/min/sec/hem to decimal value
379
+ *
380
+ * @param integer $deg the degree value
381
+ * @param integer $min the minutes value
382
+ * @param integer $sec the seconds value
383
+ * @param string $hem the hemisphere (N/E/S/W)
384
+ *
385
+ * @return float the decinmal value
386
+ * @access private
387
+ *
388
+ */
389
+ private function _dms2d($deg, $min, $sec, $hem)
390
+ {
391
+ $deg = $deg - 0;
392
+ $min = $min - 0;
393
+
394
+ $sign = ($hem == 'W' || $hem == 'S') ? -1 : 1;
395
+ return ((($sec/60+$min)/60)+$deg) * $sign;
396
+ }
397
+
398
+ /**
399
+ * convert lat/lng in decimal to deg/min/sec/hem
400
+ *
401
+ * @param float $data the decimal value
402
+ * @param string $latlng either LAT or LNG so we can determine the HEM value
403
+ *
404
+ * @return string
405
+ * @access private
406
+ *
407
+ */
408
+ private function _d2Dms($data, $latlng)
409
+ {
410
+ $deg = 0;
411
+ $min = 0;
412
+ $sec = 0;
413
+ $msec = 0;
414
+ $hem = '';
415
+
416
+ if ($latlng == 'LAT') {
417
+ $hem = ($data > 0) ? 'N' : 'S';
418
+ } else {
419
+ $hem = ($data > 0) ? 'E' : 'W';
420
+ }
421
+
422
+ $data = abs($data);
423
+
424
+ $deg = (int)$data;
425
+ $min = (int)(($data - $deg) * 60);
426
+ $sec = (int)(((($data - $deg) * 60) - $min) * 60);
427
+ $msec = round((((((($data - $deg) * 60) - $min) * 60) - $sec) * 1000));
428
+
429
+ return sprintf('%d %02d %02d.%03d %s', $deg, $min, $sec, round($msec), $hem);
430
+ }
431
+ }
432
+
433
+ /*
434
+ * Local variables:
435
+ * tab-width: 4
436
+ * c-basic-offset: 4
437
+ * c-hanging-comment-ender-p: nil
438
+ * End:
439
+ */
440
+ ?>
includes/Net/DNS2/RR/LP.php ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2013, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2013 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.3.1
49
+ *
50
+ */
51
+
52
+ /**
53
+ * LP Resource Record - RFC6742 section 2.4
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | Preference | /
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /
59
+ * / /
60
+ * / FQDN /
61
+ * / /
62
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
+ *
64
+ * @category Networking
65
+ * @package Net_DNS2
66
+ * @author Mike Pultz <mike@mikepultz.com>
67
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
68
+ * @link http://pear.php.net/package/Net_DNS2
69
+ * @see Net_DNS2_RR
70
+ *
71
+ */
72
+ class Net_DNS2_RR_LP extends Net_DNS2_RR
73
+ {
74
+ /*
75
+ * The preference
76
+ */
77
+ public $preference;
78
+
79
+ /*
80
+ * The fdqn field
81
+ */
82
+ public $fqdn;
83
+
84
+ /**
85
+ * method to return the rdata portion of the packet as a string
86
+ *
87
+ * @return string
88
+ * @access protected
89
+ *
90
+ */
91
+ protected function rrToString()
92
+ {
93
+ return $this->preference . ' ' . $this->fqdn . '.';
94
+ }
95
+
96
+ /**
97
+ * parses the rdata portion from a standard DNS config line
98
+ *
99
+ * @param array $rdata a string split line of values for the rdata
100
+ *
101
+ * @return boolean
102
+ * @access protected
103
+ *
104
+ */
105
+ protected function rrFromString(array $rdata)
106
+ {
107
+ $this->preference = array_shift($rdata);
108
+ $this->fqdn = trim(array_shift($rdata), '.');
109
+
110
+ return true;
111
+ }
112
+
113
+ /**
114
+ * parses the rdata of the Net_DNS2_Packet object
115
+ *
116
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
117
+ *
118
+ * @return boolean
119
+ * @access protected
120
+ *
121
+ */
122
+ protected function rrSet(Net_DNS2_Packet &$packet)
123
+ {
124
+ if ($this->rdlength > 0) {
125
+
126
+ //
127
+ // parse the preference
128
+ //
129
+ $x = unpack('npreference', $this->rdata);
130
+ $this->preference = $x['preference'];
131
+ $offset = $packet->offset + 2;
132
+
133
+ //
134
+ // get the hostname
135
+ //
136
+ $this->fqdn = Net_DNS2_Packet::expand($packet, $offset);
137
+
138
+ return true;
139
+ }
140
+
141
+ return false;
142
+ }
143
+
144
+ /**
145
+ * returns the rdata portion of the DNS packet
146
+ *
147
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
148
+ * compressed names
149
+ *
150
+ * @return mixed either returns a binary packed
151
+ * string or null on failure
152
+ * @access protected
153
+ *
154
+ */
155
+ protected function rrGet(Net_DNS2_Packet &$packet)
156
+ {
157
+ if (strlen($this->fqdn) > 0) {
158
+
159
+ $data = pack('n', $this->preference);
160
+ $packet->offset += 2;
161
+
162
+ $data .= $packet->compress($this->fqdn, $packet->offset);
163
+ return $data;
164
+ }
165
+
166
+ return null;
167
+ }
168
+ }
169
+
170
+ /*
171
+ * Local variables:
172
+ * tab-width: 4
173
+ * c-basic-offset: 4
174
+ * c-hanging-comment-ender-p: nil
175
+ * End:
176
+ */
177
+ ?>
includes/Net/DNS2/RR/MX.php ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * MX Resource Record - RFC1035 section 3.3.9
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | PREFERENCE |
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * / EXCHANGE /
59
+ * / /
60
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
61
+ *
62
+ * @category Networking
63
+ * @package Net_DNS2
64
+ * @author Mike Pultz <mike@mikepultz.com>
65
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
66
+ * @link http://pear.php.net/package/Net_DNS2
67
+ * @see Net_DNS2_RR
68
+ *
69
+ */
70
+ class Net_DNS2_RR_MX extends Net_DNS2_RR
71
+ {
72
+ /*
73
+ * the preference for this mail exchanger
74
+ */
75
+ public $preference;
76
+
77
+ /*
78
+ * the hostname of the mail exchanger
79
+ */
80
+ public $exchange;
81
+
82
+ /**
83
+ * method to return the rdata portion of the packet as a string
84
+ *
85
+ * @return string
86
+ * @access protected
87
+ *
88
+ */
89
+ protected function rrToString()
90
+ {
91
+ return $this->preference . ' ' . $this->cleanString($this->exchange) . '.';
92
+ }
93
+
94
+ /**
95
+ * parses the rdata portion from a standard DNS config line
96
+ *
97
+ * @param array $rdata a string split line of values for the rdata
98
+ *
99
+ * @return boolean
100
+ * @access protected
101
+ *
102
+ */
103
+ protected function rrFromString(array $rdata)
104
+ {
105
+ $this->preference = array_shift($rdata);
106
+ $this->exchange = $this->cleanString(array_shift($rdata));
107
+
108
+ return true;
109
+ }
110
+
111
+ /**
112
+ * parses the rdata of the Net_DNS2_Packet object
113
+ *
114
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
115
+ *
116
+ * @return boolean
117
+ * @access protected
118
+ *
119
+ */
120
+ protected function rrSet(Net_DNS2_Packet &$packet)
121
+ {
122
+ if ($this->rdlength > 0) {
123
+
124
+ //
125
+ // parse the preference
126
+ //
127
+ $x = unpack('npreference', $this->rdata);
128
+ $this->preference = $x['preference'];
129
+
130
+ //
131
+ // get the exchange entry server)
132
+ //
133
+ $offset = $packet->offset + 2;
134
+ $this->exchange = Net_DNS2_Packet::expand($packet, $offset);
135
+
136
+ return true;
137
+ }
138
+
139
+ return false;
140
+ }
141
+
142
+ /**
143
+ * returns the rdata portion of the DNS packet
144
+ *
145
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
146
+ * compressed names
147
+ *
148
+ * @return mixed either returns a binary packed
149
+ * string or null on failure
150
+ * @access protected
151
+ *
152
+ */
153
+ protected function rrGet(Net_DNS2_Packet &$packet)
154
+ {
155
+ if (strlen($this->exchange) > 0) {
156
+
157
+ $data = pack('n', $this->preference);
158
+ $packet->offset += 2;
159
+
160
+ $data .= $packet->compress($this->exchange, $packet->offset);
161
+ return $data;
162
+ }
163
+
164
+ return null;
165
+ }
166
+ }
167
+
168
+ /*
169
+ * Local variables:
170
+ * tab-width: 4
171
+ * c-basic-offset: 4
172
+ * c-hanging-comment-ender-p: nil
173
+ * End:
174
+ */
175
+ ?>
includes/Net/DNS2/RR/NAPTR.php ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * NAPTR Resource Record - RFC2915
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
56
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
57
+ * | ORDER |
58
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
59
+ * | PREFERENCE |
60
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
61
+ * / FLAGS /
62
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
63
+ * / SERVICES /
64
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
65
+ * / REGEXP /
66
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
67
+ * / REPLACEMENT /
68
+ * / /
69
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
70
+ *
71
+ * @category Networking
72
+ * @package Net_DNS2
73
+ * @author Mike Pultz <mike@mikepultz.com>
74
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
75
+ * @link http://pear.php.net/package/Net_DNS2
76
+ * @see Net_DNS2_RR
77
+ *
78
+ */
79
+ class Net_DNS2_RR_NAPTR extends Net_DNS2_RR
80
+ {
81
+ /*
82
+ * the order in which the NAPTR records MUST be processed
83
+ */
84
+ public $order;
85
+
86
+ /*
87
+ * specifies the order in which NAPTR records with equal "order"
88
+ * values SHOULD be processed
89
+ */
90
+ public $preference;
91
+
92
+ /*
93
+ * rewrite flags
94
+ */
95
+ public $flags;
96
+
97
+ /*
98
+ * Specifies the service(s) available down this rewrite path
99
+ */
100
+ public $services;
101
+
102
+ /*
103
+ * regular expression
104
+ */
105
+ public $regexp;
106
+
107
+ /*
108
+ * The next NAME to query for NAPTR, SRV, or address records
109
+ * depending on the value of the flags field
110
+ */
111
+ public $replacement;
112
+
113
+ /**
114
+ * method to return the rdata portion of the packet as a string
115
+ *
116
+ * @return string
117
+ * @access protected
118
+ *
119
+ */
120
+ protected function rrToString()
121
+ {
122
+ return $this->order . ' ' . $this->preference . ' ' .
123
+ $this->formatString($this->flags) . ' ' .
124
+ $this->formatString($this->services) . ' ' .
125
+ $this->formatString($this->regexp) . ' ' .
126
+ $this->cleanString($this->replacement) . '.';
127
+ }
128
+
129
+ /**
130
+ * parses the rdata portion from a standard DNS config line
131
+ *
132
+ * @param array $rdata a string split line of values for the rdata
133
+ *
134
+ * @return boolean
135
+ * @access protected
136
+ *
137
+ */
138
+ protected function rrFromString(array $rdata)
139
+ {
140
+ $this->order = array_shift($rdata);
141
+ $this->preference = array_shift($rdata);
142
+
143
+ $data = $this->buildString($rdata);
144
+ if (count($data) == 4) {
145
+
146
+ $this->flags = $data[0];
147
+ $this->services = $data[1];
148
+ $this->regexp = $data[2];
149
+ $this->replacement = $this->cleanString($data[3]);
150
+
151
+ return true;
152
+ }
153
+
154
+ return false;
155
+ }
156
+
157
+ /**
158
+ * parses the rdata of the Net_DNS2_Packet object
159
+ *
160
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
161
+ *
162
+ * @return boolean
163
+ * @access protected
164
+ *
165
+ */
166
+ protected function rrSet(Net_DNS2_Packet &$packet)
167
+ {
168
+ if ($this->rdlength > 0) {
169
+
170
+ //
171
+ // unpack the order and preference
172
+ //
173
+ $x = unpack('norder/npreference', $this->rdata);
174
+
175
+ $this->order = $x['order'];
176
+ $this->preference = $x['preference'];
177
+
178
+ $offset = $packet->offset + 4;
179
+
180
+ $this->flags = Net_DNS2_Packet::label($packet, $offset);
181
+ $this->services = Net_DNS2_Packet::label($packet, $offset);
182
+ $this->regexp = Net_DNS2_Packet::label($packet, $offset);
183
+
184
+ $this->replacement = Net_DNS2_Packet::expand($packet, $offset);
185
+
186
+ return true;
187
+ }
188
+
189
+ return false;
190
+ }
191
+
192
+ /**
193
+ * returns the rdata portion of the DNS packet
194
+ *
195
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
196
+ * compressed names
197
+ *
198
+ * @return mixed either returns a binary packed
199
+ * string or null on failure
200
+ * @access protected
201
+ *
202
+ */
203
+ protected function rrGet(Net_DNS2_Packet &$packet)
204
+ {
205
+ if ( (isset($this->order)) && (strlen($this->services) > 0) ) {
206
+
207
+ $data = pack('nn', $this->order, $this->preference);
208
+
209
+ $data .= chr(strlen($this->flags)) . $this->flags;
210
+ $data .= chr(strlen($this->services)) . $this->services;
211
+ $data .= chr(strlen($this->regexp)) . $this->regexp;
212
+
213
+ $packet->offset += strlen($data);
214
+
215
+ $data .= $packet->compress($this->replacement, $packet->offset);
216
+
217
+ return $data;
218
+ }
219
+
220
+ return null;
221
+ }
222
+ }
223
+
224
+ /*
225
+ * Local variables:
226
+ * tab-width: 4
227
+ * c-basic-offset: 4
228
+ * c-hanging-comment-ender-p: nil
229
+ * End:
230
+ */
231
+ ?>
includes/Net/DNS2/RR/NID.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2013, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2013 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.3.1
49
+ *
50
+ */
51
+
52
+ /**
53
+ * NID Resource Record - RFC6742 section 2.1
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | Preference | |
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
59
+ * | NodeID |
60
+ * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
+ * | |
62
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
+ *
64
+ * @category Networking
65
+ * @package Net_DNS2
66
+ * @author Mike Pultz <mike@mikepultz.com>
67
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
68
+ * @link http://pear.php.net/package/Net_DNS2
69
+ * @see Net_DNS2_RR
70
+ *
71
+ */
72
+ class Net_DNS2_RR_NID extends Net_DNS2_RR
73
+ {
74
+ /*
75
+ * The preference
76
+ */
77
+ public $preference;
78
+
79
+ /*
80
+ * The node ID field
81
+ */
82
+ public $nodeid;
83
+
84
+ /**
85
+ * method to return the rdata portion of the packet as a string
86
+ *
87
+ * @return string
88
+ * @access protected
89
+ *
90
+ */
91
+ protected function rrToString()
92
+ {
93
+ return $this->preference . ' ' . $this->nodeid;
94
+ }
95
+
96
+ /**
97
+ * parses the rdata portion from a standard DNS config line
98
+ *
99
+ * @param array $rdata a string split line of values for the rdata
100
+ *
101
+ * @return boolean
102
+ * @access protected
103
+ *
104
+ */
105
+ protected function rrFromString(array $rdata)
106
+ {
107
+ $this->preference = array_shift($rdata);
108
+ $this->nodeid = array_shift($rdata);
109
+
110
+ return true;
111
+ }
112
+
113
+ /**
114
+ * parses the rdata of the Net_DNS2_Packet object
115
+ *
116
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
117
+ *
118
+ * @return boolean
119
+ * @access protected
120
+ *
121
+ */
122
+ protected function rrSet(Net_DNS2_Packet &$packet)
123
+ {
124
+ if ($this->rdlength > 0) {
125
+
126
+ //
127
+ // unpack the values
128
+ //
129
+ $x = unpack('npreference/n4nodeid', $this->rdata);
130
+
131
+ $this->preference = $x['preference'];
132
+
133
+ //
134
+ // build the node id
135
+ //
136
+ $this->nodeid = dechex($x['nodeid1']) . ':' .
137
+ dechex($x['nodeid2']) . ':' .
138
+ dechex($x['nodeid3']) . ':' .
139
+ dechex($x['nodeid4']);
140
+
141
+ return true;
142
+ }
143
+
144
+ return false;
145
+ }
146
+
147
+ /**
148
+ * returns the rdata portion of the DNS packet
149
+ *
150
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
151
+ * compressed names
152
+ *
153
+ * @return mixed either returns a binary packed
154
+ * string or null on failure
155
+ * @access protected
156
+ *
157
+ */
158
+ protected function rrGet(Net_DNS2_Packet &$packet)
159
+ {
160
+ if (strlen($this->nodeid) > 0) {
161
+
162
+ //
163
+ // break out the node id
164
+ //
165
+ $n = explode(':', $this->nodeid);
166
+
167
+ //
168
+ // pack the data
169
+ //
170
+ return pack(
171
+ 'n5', $this->preference, hexdec($n[0]), hexdec($n[1]),
172
+ hexdec($n[2]), hexdec($n[3])
173
+ );
174
+ }
175
+
176
+ return null;
177
+ }
178
+ }
179
+
180
+ /*
181
+ * Local variables:
182
+ * tab-width: 4
183
+ * c-basic-offset: 4
184
+ * c-hanging-comment-ender-p: nil
185
+ * End:
186
+ */
187
+ ?>
includes/Net/DNS2/RR/NIMLOC.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * NIMLOCK Resource Record - undefined; the rdata is simply used as-is in it's
54
+ * binary format, so not process has to be done.
55
+ *
56
+ * @category Networking
57
+ * @package Net_DNS2
58
+ * @author Mike Pultz <mike@mikepultz.com>
59
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
60
+ * @link http://pear.php.net/package/Net_DNS2
61
+ * @see Net_DNS2_RR
62
+ *
63
+ */
64
+ class Net_DNS2_RR_NIMLOCK extends Net_DNS2_RR
65
+ {
66
+ /**
67
+ * method to return the rdata portion of the packet as a string
68
+ *
69
+ * @return string
70
+ * @access protected
71
+ *
72
+ */
73
+ protected function rrToString()
74
+ {
75
+ return '';
76
+ }
77
+
78
+ /**
79
+ * parses the rdata portion from a standard DNS config line
80
+ *
81
+ * @param array $rdata a string split line of values for the rdata
82
+ *
83
+ * @return boolean
84
+ * @access protected
85
+ *
86
+ */
87
+ protected function rrFromString(array $rdata)
88
+ {
89
+ return true;
90
+ }
91
+
92
+ /**
93
+ * parses the rdata of the Net_DNS2_Packet object
94
+ *
95
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
96
+ *
97
+ * @return boolean
98
+ * @access protected
99
+ *
100
+ */
101
+ protected function rrSet(Net_DNS2_Packet &$packet)
102
+ {
103
+ return true;
104
+ }
105
+
106
+ /**
107
+ * returns the rdata portion of the DNS packet
108
+ *
109
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
110
+ * compressed names
111
+ *
112
+ * @return mixed either returns a binary packed
113
+ * string or null on failure
114
+ * @access protected
115
+ *
116
+ */
117
+ protected function rrGet(Net_DNS2_Packet &$packet)
118
+ {
119
+ return $this->rdata;
120
+ }
121
+ }
122
+
123
+ /*
124
+ * Local variables:
125
+ * tab-width: 4
126
+ * c-basic-offset: 4
127
+ * c-hanging-comment-ender-p: nil
128
+ * End:
129
+ */
130
+ ?>
includes/Net/DNS2/RR/NS.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * NS Resource Record - RFC1035 section 3.3.11
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * / NSDNAME /
57
+ * / /
58
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
59
+ *
60
+ * @category Networking
61
+ * @package Net_DNS2
62
+ * @author Mike Pultz <mike@mikepultz.com>
63
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
64
+ * @link http://pear.php.net/package/Net_DNS2
65
+ * @see Net_DNS2_RR
66
+ *
67
+ */
68
+ class Net_DNS2_RR_NS extends Net_DNS2_RR
69
+ {
70
+ /*
71
+ * the hostname of the DNS server
72
+ */
73
+ public $nsdname;
74
+
75
+ /**
76
+ * method to return the rdata portion of the packet as a string
77
+ *
78
+ * @return string
79
+ * @access protected
80
+ *
81
+ */
82
+ protected function rrToString()
83
+ {
84
+ return $this->cleanString($this->nsdname) . '.';
85
+ }
86
+
87
+ /**
88
+ * parses the rdata portion from a standard DNS config line
89
+ *
90
+ * @param array $rdata a string split line of values for the rdata
91
+ *
92
+ * @return boolean
93
+ * @access protected
94
+ *
95
+ */
96
+ protected function rrFromString(array $rdata)
97
+ {
98
+ $this->nsdname = $this->cleanString(array_shift($rdata));
99
+ return true;
100
+ }
101
+
102
+ /**
103
+ * parses the rdata of the Net_DNS2_Packet object
104
+ *
105
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
106
+ *
107
+ * @return boolean
108
+ * @access protected
109
+ *
110
+ */
111
+ protected function rrSet(Net_DNS2_Packet &$packet)
112
+ {
113
+ if ($this->rdlength > 0) {
114
+
115
+ $offset = $packet->offset;
116
+ $this->nsdname = Net_DNS2_Packet::expand($packet, $offset);
117
+
118
+ return true;
119
+ }
120
+
121
+ return false;
122
+ }
123
+
124
+ /**
125
+ * returns the rdata portion of the DNS packet
126
+ *
127
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
128
+ * compressed names
129
+ *
130
+ * @return mixed either returns a binary packed
131
+ * string or null on failure
132
+ * @access protected
133
+ *
134
+ */
135
+ protected function rrGet(Net_DNS2_Packet &$packet)
136
+ {
137
+ if (strlen($this->nsdname) > 0) {
138
+
139
+ return $packet->compress($this->nsdname, $packet->offset);
140
+ }
141
+
142
+ return null;
143
+ }
144
+ }
145
+
146
+ /*
147
+ * Local variables:
148
+ * tab-width: 4
149
+ * c-basic-offset: 4
150
+ * c-hanging-comment-ender-p: nil
151
+ * End:
152
+ */
153
+ ?>
includes/Net/DNS2/RR/NSAP.php ADDED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * NSAP Resource Record - RFC1706
54
+ *
55
+ * |--------------|
56
+ * | <-- IDP --> |
57
+ * |--------------|-------------------------------------|
58
+ * | AFI | IDI | <-- DSP --> |
59
+ * |-----|--------|-------------------------------------|
60
+ * | 47 | 0005 | DFI | AA |Rsvd | RD |Area | ID |Sel |
61
+ * |-----|--------|-----|----|-----|----|-----|----|----|
62
+ * octets | 1 | 2 | 1 | 3 | 2 | 2 | 2 | 6 | 1 |
63
+ * |-----|--------|-----|----|-----|----|-----|----|----|
64
+ *
65
+ * @category Networking
66
+ * @package Net_DNS2
67
+ * @author Mike Pultz <mike@mikepultz.com>
68
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
69
+ * @link http://pear.php.net/package/Net_DNS2
70
+ * @see Net_DNS2_RR
71
+ *
72
+ */
73
+ class Net_DNS2_RR_NSAP extends Net_DNS2_RR
74
+ {
75
+ public $afi;
76
+ public $idi;
77
+ public $dfi;
78
+ public $aa;
79
+ public $rsvd;
80
+ public $rd;
81
+ public $area;
82
+ public $id;
83
+ public $sel;
84
+
85
+ /**
86
+ * method to return the rdata portion of the packet as a string
87
+ *
88
+ * @return string
89
+ * @access protected
90
+ *
91
+ */
92
+ protected function rrToString()
93
+ {
94
+ return $this->cleanString($this->afi) . '.' .
95
+ $this->cleanString($this->idi) . '.' .
96
+ $this->cleanString($this->dfi) . '.' .
97
+ $this->cleanString($this->aa) . '.' .
98
+ $this->cleanString($this->rsvd) . '.' .
99
+ $this->cleanString($this->rd) . '.' .
100
+ $this->cleanString($this->area) . '.' .
101
+ $this->cleanString($this->id) . '.' .
102
+ $this->sel;
103
+ }
104
+
105
+ /**
106
+ * parses the rdata portion from a standard DNS config line
107
+ *
108
+ * @param array $rdata a string split line of values for the rdata
109
+ *
110
+ * @return boolean
111
+ * @access protected
112
+ *
113
+ */
114
+ protected function rrFromString(array $rdata)
115
+ {
116
+ $data = strtolower(trim(array_shift($rdata)));
117
+
118
+ //
119
+ // there is no real standard for format, so we can't rely on the fact that
120
+ // the value will come in with periods separating the values- so strip
121
+ // them out if they're included, and parse without them.
122
+ //
123
+ $data = str_replace(array('.', '0x'), '', $data);
124
+
125
+ //
126
+ // unpack it as ascii characters
127
+ //
128
+ $x = unpack('A2afi/A4idi/A2dfi/A6aa/A4rsvd/A4rd/A4area/A12id/A2sel', $data);
129
+
130
+ //
131
+ // make sure the afi value is 47
132
+ //
133
+ if ($x['afi'] == 47) {
134
+
135
+ $this->afi = '0x' . $x['afi'];
136
+ $this->idi = $x['idi'];
137
+ $this->dfi = $x['dfi'];
138
+ $this->aa = $x['aa'];
139
+ $this->rsvd = $x['rsvd'];
140
+ $this->rd = $x['rd'];
141
+ $this->area = $x['area'];
142
+ $this->id = $x['id'];
143
+ $this->sel = $x['sel'];
144
+
145
+ return true;
146
+ }
147
+
148
+ return false;
149
+ }
150
+
151
+ /**
152
+ * parses the rdata of the Net_DNS2_Packet object
153
+ *
154
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
155
+ *
156
+ * @return boolean
157
+ * @access protected
158
+ *
159
+ */
160
+ protected function rrSet(Net_DNS2_Packet &$packet)
161
+ {
162
+ if ($this->rdlength == 20) {
163
+
164
+ //
165
+ // get the AFI value
166
+ //
167
+ $this->afi = dechex(ord($this->rdata[0]));
168
+
169
+ //
170
+ // we only support AFI 47- there arent' any others defined.
171
+ //
172
+ if ($this->afi == 47) {
173
+
174
+ //
175
+ // unpack the rest of the values
176
+ //
177
+ $x = unpack(
178
+ 'Cafi/nidi/Cdfi/C3aa/nrsvd/nrd/narea/Nidh/nidl/Csel',
179
+ $this->rdata
180
+ );
181
+
182
+ $this->afi = sprintf('0x%02x', $x['afi']);
183
+ $this->idi = sprintf('%04x', $x['idi']);
184
+ $this->dfi = sprintf('%02x', $x['dfi']);
185
+ $this->aa = sprintf(
186
+ '%06x', $x['aa1'] << 16 | $x['aa2'] << 8 | $x['aa3']
187
+ );
188
+ $this->rsvd = sprintf('%04x', $x['rsvd']);
189
+ $this->rd = sprintf('%04x', $x['rd']);
190
+ $this->area = sprintf('%04x', $x['area']);
191
+ $this->id = sprintf('%08x', $x['idh']) .
192
+ sprintf('%04x', $x['idl']);
193
+ $this->sel = sprintf('%02x', $x['sel']);
194
+
195
+ return true;
196
+ }
197
+ }
198
+
199
+ return false;
200
+ }
201
+
202
+ /**
203
+ * returns the rdata portion of the DNS packet
204
+ *
205
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
206
+ * compressed names
207
+ *
208
+ * @return mixed either returns a binary packed
209
+ * string or null on failure
210
+ * @access protected
211
+ *
212
+ */
213
+ protected function rrGet(Net_DNS2_Packet &$packet)
214
+ {
215
+ if ($this->afi == 0x47) {
216
+
217
+ //
218
+ // build the aa field
219
+ //
220
+ $aa = unpack('A2x/A2y/A2z', $this->aa);
221
+
222
+ //
223
+ // build the id field
224
+ //
225
+ $id = unpack('A8a/A4b', $this->id);
226
+
227
+ //
228
+ $data = pack(
229
+ 'CnCCCCnnnNnC',
230
+ hexdec($this->afi),
231
+ hexdec($this->idi),
232
+ hexdec($this->dfi),
233
+ hexdec($aa['x']),
234
+ hexdec($aa['y']),
235
+ hexdec($aa['z']),
236
+ hexdec($this->rsvd),
237
+ hexdec($this->rd),
238
+ hexdec($this->area),
239
+ hexdec($id['a']),
240
+ hexdec($id['b']),
241
+ hexdec($this->sel)
242
+ );
243
+
244
+ if (strlen($data) == 20) {
245
+
246
+ $packet->offset += 20;
247
+ return $data;
248
+ }
249
+ }
250
+
251
+ return null;
252
+ }
253
+ }
254
+
255
+ /*
256
+ * Local variables:
257
+ * tab-width: 4
258
+ * c-basic-offset: 4
259
+ * c-hanging-comment-ender-p: nil
260
+ * End:
261
+ */
262
+ ?>
includes/Net/DNS2/RR/NSEC.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * NSEC Resource Record - RFC3845 section 2.1
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * / Next Domain Name /
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59
+ * / List of Type Bit Map(s) /
60
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
+ *
62
+ * @category Networking
63
+ * @package Net_DNS2
64
+ * @author Mike Pultz <mike@mikepultz.com>
65
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
66
+ * @link http://pear.php.net/package/Net_DNS2
67
+ * @see Net_DNS2_RR
68
+ *
69
+ */
70
+ class Net_DNS2_RR_NSEC extends Net_DNS2_RR
71
+ {
72
+ /*
73
+ * The next owner name
74
+ */
75
+ public $next_domain_name;
76
+
77
+ /*
78
+ * identifies the RRset types that exist at the NSEC RR's owner name.
79
+ */
80
+ public $type_bit_maps = array();
81
+
82
+ /**
83
+ * method to return the rdata portion of the packet as a string
84
+ *
85
+ * @return string
86
+ * @access protected
87
+ *
88
+ */
89
+ protected function rrToString()
90
+ {
91
+ $data = $this->cleanString($this->next_domain_name) . '.';
92
+
93
+ foreach ($this->type_bit_maps as $rr) {
94
+
95
+ $data .= ' ' . $rr;
96
+ }
97
+
98
+ return $data;
99
+ }
100
+
101
+ /**
102
+ * parses the rdata portion from a standard DNS config line
103
+ *
104
+ * @param array $rdata a string split line of values for the rdata
105
+ *
106
+ * @return boolean
107
+ * @access protected
108
+ *
109
+ */
110
+ protected function rrFromString(array $rdata)
111
+ {
112
+ $this->next_domain_name = $this->cleanString(array_shift($rdata));
113
+ $this->type_bit_maps = $rdata;
114
+
115
+ return true;
116
+ }
117
+
118
+ /**
119
+ * parses the rdata of the Net_DNS2_Packet object
120
+ *
121
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
122
+ *
123
+ * @return boolean
124
+ * @access protected
125
+ *
126
+ */
127
+ protected function rrSet(Net_DNS2_Packet &$packet)
128
+ {
129
+ if ($this->rdlength > 0) {
130
+
131
+ //
132
+ // expand the next domain name
133
+ //
134
+ $offset = $packet->offset;
135
+ $this->next_domain_name = Net_DNS2_Packet::expand($packet, $offset);
136
+
137
+ //
138
+ // parse out the RR's from the bitmap
139
+ //
140
+ $this->type_bit_maps = Net_DNS2_BitMap::bitMapToArray(
141
+ substr($this->rdata, $offset - $packet->offset)
142
+ );
143
+
144
+ return true;
145
+ }
146
+
147
+ return false;
148
+ }
149
+
150
+ /**
151
+ * returns the rdata portion of the DNS packet
152
+ *
153
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
154
+ * compressed names
155
+ *
156
+ * @return mixed either returns a binary packed
157
+ * string or null on failure
158
+ * @access protected
159
+ *
160
+ */
161
+ protected function rrGet(Net_DNS2_Packet &$packet)
162
+ {
163
+ if (strlen($this->next_domain_name) > 0) {
164
+
165
+ $data = $packet->compress($this->next_domain_name, $packet->offset);
166
+ $bitmap = Net_DNS2_BitMap::arrayToBitMap($this->type_bit_maps);
167
+
168
+ $packet->offset += strlen($bitmap);
169
+
170
+ return $data . $bitmap;
171
+ }
172
+
173
+ return null;
174
+ }
175
+ }
176
+
177
+ /*
178
+ * Local variables:
179
+ * tab-width: 4
180
+ * c-basic-offset: 4
181
+ * c-hanging-comment-ender-p: nil
182
+ * End:
183
+ */
184
+ ?>
includes/Net/DNS2/RR/NSEC3.php ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * NSEC3 Resource Record - RFC5155 section 3.2
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | Hash Alg. | Flags | Iterations |
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59
+ * | Salt Length | Salt /
60
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
+ * | Hash Length | Next Hashed Owner Name /
62
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
+ * / Type Bit Maps /
64
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65
+ *
66
+ * @category Networking
67
+ * @package Net_DNS2
68
+ * @author Mike Pultz <mike@mikepultz.com>
69
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
70
+ * @link http://pear.php.net/package/Net_DNS2
71
+ * @see Net_DNS2_RR
72
+ *
73
+ */
74
+ class Net_DNS2_RR_NSEC3 extends Net_DNS2_RR
75
+ {
76
+ /*
77
+ * Algorithm to use
78
+ */
79
+ public $algorithm;
80
+
81
+ /*
82
+ * flags
83
+ */
84
+ public $flags;
85
+
86
+ /*
87
+ * defines the number of additional times the hash is performed.
88
+ */
89
+ public $iterations;
90
+
91
+ /*
92
+ * the length of the salt- not displayed
93
+ */
94
+ public $salt_length;
95
+
96
+ /*
97
+ * the salt
98
+ */
99
+ public $salt;
100
+
101
+ /*
102
+ * the length of the hash value
103
+ */
104
+ public $hash_length;
105
+
106
+ /*
107
+ * the hashed value of the owner name
108
+ */
109
+ public $hashed_owner_name;
110
+
111
+ /*
112
+ * array of RR type names
113
+ */
114
+ public $type_bit_maps = array();
115
+
116
+ /**
117
+ * method to return the rdata portion of the packet as a string
118
+ *
119
+ * @return string
120
+ * @access protected
121
+ *
122
+ */
123
+ protected function rrToString()
124
+ {
125
+ $out = $this->algorithm . ' ' . $this->flags . ' ' . $this->iterations . ' ';
126
+
127
+ //
128
+ // per RFC5155, the salt_length value isn't displayed, and if the salt
129
+ // is empty, the salt is displayed as '-'
130
+ //
131
+ if ($this->salt_length > 0) {
132
+
133
+ $out .= $this->salt;
134
+ } else {
135
+
136
+ $out .= '-';
137
+ }
138
+
139
+ //
140
+ // per RFC5255 the hash length isn't shown
141
+ //
142
+ $out .= ' ' . $this->hashed_owner_name;
143
+
144
+ //
145
+ // show the RR's
146
+ //
147
+ foreach ($this->type_bit_maps as $rr) {
148
+
149
+ $out .= ' ' . strtoupper($rr);
150
+ }
151
+
152
+ return $out;
153
+ }
154
+
155
+ /**
156
+ * parses the rdata portion from a standard DNS config line
157
+ *
158
+ * @param array $rdata a string split line of values for the rdata
159
+ *
160
+ * @return boolean
161
+ * @access protected
162
+ *
163
+ */
164
+ protected function rrFromString(array $rdata)
165
+ {
166
+ $this->algorithm = array_shift($rdata);
167
+ $this->flags = array_shift($rdata);
168
+ $this->iterations = array_shift($rdata);
169
+
170
+ //
171
+ // an empty salt is represented as '-' per RFC5155 section 3.3
172
+ //
173
+ $salt = array_shift($rdata);
174
+ if ($salt == '-') {
175
+
176
+ $this->salt_length = 0;
177
+ $this->salt = '';
178
+ } else {
179
+
180
+ $this->salt_length = strlen(pack('H*', $salt));
181
+ $this->salt = strtoupper($salt);
182
+ }
183
+
184
+ $this->hashed_owner_name = array_shift($rdata);
185
+ $this->hash_length = strlen(base64_decode($this->hashed_owner_name));
186
+
187
+ $this->type_bit_maps = $rdata;
188
+
189
+ return true;
190
+ }
191
+
192
+ /**
193
+ * parses the rdata of the Net_DNS2_Packet object
194
+ *
195
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
196
+ *
197
+ * @return boolean
198
+ * @access protected
199
+ *
200
+ */
201
+ protected function rrSet(Net_DNS2_Packet &$packet)
202
+ {
203
+ if ($this->rdlength > 0) {
204
+
205
+ //
206
+ // unpack the first values
207
+ //
208
+ $x = unpack('Calgorithm/Cflags/niterations/Csalt_length', $this->rdata);
209
+
210
+ $this->algorithm = $x['algorithm'];
211
+ $this->flags = $x['flags'];
212
+ $this->iterations = $x['iterations'];
213
+ $this->salt_length = $x['salt_length'];
214
+
215
+ $offset = 5;
216
+
217
+ if ($this->salt_length > 0) {
218
+
219
+ $x = unpack('H*', substr($this->rdata, $offset, $this->salt_length));
220
+ $this->salt = strtoupper($x[1]);
221
+ $offset += $this->salt_length;
222
+ }
223
+
224
+ //
225
+ // unpack the hash length
226
+ //
227
+ $x = unpack('@' . $offset . '/Chash_length', $this->rdata);
228
+ $offset++;
229
+
230
+ //
231
+ // copy out the hash
232
+ //
233
+ $this->hash_length = $x['hash_length'];
234
+ if ($this->hash_length > 0) {
235
+
236
+ $this->hashed_owner_name = base64_encode(
237
+ substr($this->rdata, $offset, $this->hash_length)
238
+ );
239
+ $offset += $this->hash_length;
240
+ }
241
+
242
+ //
243
+ // parse out the RR bitmap
244
+ //
245
+ $this->type_bit_maps = Net_DNS2_BitMap::bitMapToArray(
246
+ substr($this->rdata, $offset)
247
+ );
248
+
249
+ return true;
250
+ }
251
+
252
+ return false;
253
+ }
254
+
255
+ /**
256
+ * returns the rdata portion of the DNS packet
257
+ *
258
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
259
+ * compressed names
260
+ *
261
+ * @return mixed either returns a binary packed
262
+ * string or null on failure
263
+ * @access protected
264
+ *
265
+ */
266
+ protected function rrGet(Net_DNS2_Packet &$packet)
267
+ {
268
+ //
269
+ // pull the salt and build the length
270
+ //
271
+ $salt = pack('H*', $this->salt);
272
+ $this->salt_length = strlen($salt);
273
+
274
+ //
275
+ // pack the algorithm, flags, iterations and salt length
276
+ //
277
+ $data = pack(
278
+ 'CCnC',
279
+ $this->algorithm, $this->flags, $this->iterations, $this->salt_length
280
+ );
281
+ $data .= $salt;
282
+
283
+ //
284
+ // add the hash length and hash
285
+ //
286
+ $data .= chr($this->hash_length);
287
+ if ($this->hash_length > 0) {
288
+
289
+ $data .= base64_decode($this->hashed_owner_name);
290
+ }
291
+
292
+ //
293
+ // conver the array of RR names to a type bitmap
294
+ //
295
+ $data .= Net_DNS2_BitMap::arrayToBitMap($this->type_bit_maps);
296
+
297
+ $packet->offset += strlen($data);
298
+
299
+ return $data;
300
+ }
301
+ }
302
+
303
+ /*
304
+ * Local variables:
305
+ * tab-width: 4
306
+ * c-basic-offset: 4
307
+ * c-hanging-comment-ender-p: nil
308
+ * End:
309
+ */
310
+ ?>
includes/Net/DNS2/RR/NSEC3PARAM.php ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * NSEC3PARAM Resource Record - RFC5155 section 4.2
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | Hash Alg. | Flags | Iterations |
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59
+ * | Salt Length | Salt /
60
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
+ *
62
+ * @category Networking
63
+ * @package Net_DNS2
64
+ * @author Mike Pultz <mike@mikepultz.com>
65
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
66
+ * @link http://pear.php.net/package/Net_DNS2
67
+ * @see Net_DNS2_RR
68
+ *
69
+ */
70
+ class Net_DNS2_RR_NSEC3PARAM extends Net_DNS2_RR
71
+ {
72
+ /*
73
+ * Algorithm to use
74
+ *
75
+ * TODO: same as the NSEC3
76
+ */
77
+ public $algorithm;
78
+
79
+ /*
80
+ * flags
81
+ */
82
+ public $flags;
83
+
84
+ /*
85
+ * defines the number of additional times the hash is performed.
86
+ */
87
+ public $iterations;
88
+
89
+ /*
90
+ * the length of the salt- not displayed
91
+ */
92
+ public $salt_length;
93
+
94
+ /*
95
+ * the salt
96
+ */
97
+ public $salt;
98
+
99
+ /**
100
+ * method to return the rdata portion of the packet as a string
101
+ *
102
+ * @return string
103
+ * @access protected
104
+ *
105
+ */
106
+ protected function rrToString()
107
+ {
108
+ $out = $this->algorithm . ' ' . $this->flags . ' ' . $this->iterations . ' ';
109
+
110
+ //
111
+ // per RFC5155, the salt_length value isn't displayed, and if the salt
112
+ // is empty, the salt is displayed as "-"
113
+ //
114
+ if ($this->salt_length > 0) {
115
+
116
+ $out .= $this->salt;
117
+ } else {
118
+
119
+ $out .= '-';
120
+ }
121
+
122
+ return $out;
123
+ }
124
+
125
+ /**
126
+ * parses the rdata portion from a standard DNS config line
127
+ *
128
+ * @param array $rdata a string split line of values for the rdata
129
+ *
130
+ * @return boolean
131
+ * @access protected
132
+ *
133
+ */
134
+ protected function rrFromString(array $rdata)
135
+ {
136
+ $this->algorithm = array_shift($rdata);
137
+ $this->flags = array_shift($rdata);
138
+ $this->iterations = array_shift($rdata);
139
+
140
+ $salt = array_shift($rdata);
141
+ if ($salt == '-') {
142
+
143
+ $this->salt_length = 0;
144
+ $this->salt = '';
145
+ } else {
146
+
147
+ $this->salt_length = strlen(pack('H*', $salt));
148
+ $this->salt = strtoupper($salt);
149
+ }
150
+
151
+ return true;
152
+ }
153
+
154
+ /**
155
+ * parses the rdata of the Net_DNS2_Packet object
156
+ *
157
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
158
+ *
159
+ * @return boolean
160
+ * @access protected
161
+ *
162
+ */
163
+ protected function rrSet(Net_DNS2_Packet &$packet)
164
+ {
165
+ if ($this->rdlength > 0) {
166
+
167
+ $x = unpack('Calgorithm/Cflags/niterations/Csalt_length', $this->rdata);
168
+
169
+ $this->algorithm = $x['algorithm'];
170
+ $this->flags = $x['flags'];
171
+ $this->iterations = $x['iterations'];
172
+ $this->salt_length = $x['salt_length'];
173
+
174
+ if ($this->salt_length > 0) {
175
+
176
+ $x = unpack('H*', substr($this->rdata, 5, $this->salt_length));
177
+ $this->salt = strtoupper($x[1]);
178
+ }
179
+
180
+ return true;
181
+ }
182
+
183
+ return false;
184
+ }
185
+
186
+ /**
187
+ * returns the rdata portion of the DNS packet
188
+ *
189
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
190
+ * compressed names
191
+ *
192
+ * @return mixed either returns a binary packed
193
+ * string or null on failure
194
+ * @access protected
195
+ *
196
+ */
197
+ protected function rrGet(Net_DNS2_Packet &$packet)
198
+ {
199
+ $salt = pack('H*', $this->salt);
200
+ $this->salt_length = strlen($salt);
201
+
202
+ $data = pack(
203
+ 'CCnC',
204
+ $this->algorithm, $this->flags, $this->iterations, $this->salt_length
205
+ ) . $salt;
206
+
207
+ $packet->offset += strlen($data);
208
+
209
+ return $data;
210
+ }
211
+ }
212
+
213
+ /*
214
+ * Local variables:
215
+ * tab-width: 4
216
+ * c-basic-offset: 4
217
+ * c-hanging-comment-ender-p: nil
218
+ * End:
219
+ */
220
+ ?>
includes/Net/DNS2/RR/OPENPGPKEY.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2014, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2014 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.4.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * OPENPGPKEY Resource Record - https://tools.ietf.org/html/draft-ietf-dane-openpgpkey-01
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * / /
58
+ * / OpenPGP Public KeyRing /
59
+ * / /
60
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
+ *
62
+ * @category Networking
63
+ * @package Net_DNS2
64
+ * @author Mike Pultz <mike@mikepultz.com>
65
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
66
+ * @link http://pear.php.net/package/Net_DNS2
67
+ * @see Net_DNS2_RR
68
+ *
69
+ */
70
+ class Net_DNS2_RR_OPENPGPKEY extends Net_DNS2_RR
71
+ {
72
+ /*
73
+ * the public key
74
+ */
75
+ public $key;
76
+
77
+ /**
78
+ * method to return the rdata portion of the packet as a string
79
+ *
80
+ * @return string
81
+ * @access protected
82
+ *
83
+ */
84
+ protected function rrToString()
85
+ {
86
+ return $this->key;
87
+ }
88
+
89
+ /**
90
+ * parses the rdata portion from a standard DNS config line
91
+ *
92
+ * @param array $rdata a string split line of values for the rdata
93
+ *
94
+ * @return boolean
95
+ * @access protected
96
+ *
97
+ */
98
+ protected function rrFromString(array $rdata)
99
+ {
100
+ $this->key = array_shift($rdata);
101
+
102
+ return true;
103
+ }
104
+
105
+ /**
106
+ * parses the rdata of the Net_DNS2_Packet object
107
+ *
108
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
109
+ *
110
+ * @return boolean
111
+ * @access protected
112
+ *
113
+ */
114
+ protected function rrSet(Net_DNS2_Packet &$packet)
115
+ {
116
+ if ($this->rdlength > 0) {
117
+
118
+ $this->key = base64_encode($this->rdata);
119
+
120
+ return true;
121
+ }
122
+
123
+ return false;
124
+ }
125
+
126
+ /**
127
+ * returns the rdata portion of the DNS packet
128
+ *
129
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
130
+ * compressed names
131
+ *
132
+ * @return mixed either returns a binary packed
133
+ * string or null on failure
134
+ * @access protected
135
+ *
136
+ */
137
+ protected function rrGet(Net_DNS2_Packet &$packet)
138
+ {
139
+ if (strlen($this->key) > 0) {
140
+
141
+ $data = base64_decode($this->key);
142
+
143
+ $packet->offset += strlen($data);
144
+
145
+ return $data;
146
+ }
147
+
148
+ return null;
149
+ }
150
+ }
151
+
152
+ /*
153
+ * Local variables:
154
+ * tab-width: 4
155
+ * c-basic-offset: 4
156
+ * c-hanging-comment-ender-p: nil
157
+ * End:
158
+ */
159
+ ?>
includes/Net/DNS2/RR/OPT.php ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.0.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * OPT Resource Record - RFC2929 section 3.1
54
+ *
55
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
56
+ * | OPTION-CODE |
57
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
58
+ * | OPTION-LENGTH |
59
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
60
+ * | |
61
+ * / OPTION-DATA /
62
+ * / /
63
+ * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
64
+ *
65
+ * @category Networking
66
+ * @package Net_DNS2
67
+ * @author Mike Pultz <mike@mikepultz.com>
68
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
69
+ * @link http://pear.php.net/package/Net_DNS2
70
+ * @see Net_DNS2_RR
71
+ *
72
+ */
73
+ class Net_DNS2_RR_OPT extends Net_DNS2_RR
74
+ {
75
+ /*
76
+ * option code - assigned by IANA
77
+ */
78
+ public $option_code;
79
+
80
+ /*
81
+ * the length of the option data
82
+ */
83
+ public $option_length;
84
+
85
+ /*
86
+ * the option data
87
+ */
88
+ public $option_data;
89
+
90
+ /*
91
+ * the extended response code stored in the TTL
92
+ */
93
+ public $extended_rcode;
94
+
95
+ /*
96
+ * the implementation level
97
+ */
98
+ public $version;
99
+
100
+ /*
101
+ * the DO bit used for DNSSEC - RFC3225
102
+ */
103
+ public $do;
104
+
105
+ /*
106
+ * the extended flags
107
+ */
108
+ public $z;
109
+
110
+ /**
111
+ * Constructor - builds a new Net_DNS2_RR_OPT object; normally you wouldn't call
112
+ * this directly, but OPT RR's are a little different
113
+ *
114
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet or null to create
115
+ * an empty object
116
+ * @param array $rr an array with RR parse values or null to
117
+ * create an empty object
118
+ *
119
+ * @throws Net_DNS2_Exception
120
+ * @access public
121
+ *
122
+ */
123
+ public function __construct(Net_DNS2_Packet &$packet = null, array $rr = null)
124
+ {
125
+ //
126
+ // this is for when we're manually building an OPT RR object; we aren't
127
+ // passing in binary data to parse, we just want a clean/empty object.
128
+ //
129
+ $this->type = 'OPT';
130
+ $this->rdlength = 0;
131
+
132
+ $this->option_length = 0;
133
+ $this->extended_rcode = 0;
134
+ $this->version = 0;
135
+ $this->do = 0;
136
+ $this->z = 0;
137
+
138
+ //
139
+ // everthing else gets passed through to the parent.
140
+ //
141
+ if ( (!is_null($packet)) && (!is_null($rr)) ) {
142
+
143
+ parent::__construct($packet, $rr);
144
+ }
145
+ }
146
+
147
+ /**
148
+ * method to return the rdata portion of the packet as a string. There is no
149
+ * defintion for returning an OPT RR by string- this is just here to validate
150
+ * the binary parsing / building routines.
151
+ *
152
+ * @return string
153
+ * @access protected
154
+ *
155
+ */
156
+ protected function rrToString()
157
+ {
158
+ return $this->option_code . ' ' . $this->option_data;
159
+ }
160
+
161
+ /**
162
+ * parses the rdata portion from a standard DNS config line. There is no
163
+ * definition for parsing a OPT RR by string- this is just here to validate
164
+ * the binary parsing / building routines.
165
+ *
166
+ * @param array $rdata a string split line of values for the rdata
167
+ *
168
+ * @return boolean
169
+ * @access protected
170
+ *
171
+ */
172
+ protected function rrFromString(array $rdata)
173
+ {
174
+ $this->option_code = array_shift($rdata);
175
+ $this->option_data = array_shift($rdata);
176
+ $this->option_length = strlen($this->option_data);
177
+
178
+ $x = unpack('Cextended/Cversion/Cdo/Cz', pack('N', $this->ttl));
179
+
180
+ $this->extended_rcode = $x['extended'];
181
+ $this->version = $x['version'];
182
+ $this->do = ($x['do'] >> 7);
183
+ $this->z = $x['z'];
184
+
185
+ return true;
186
+ }
187
+
188
+ /**
189
+ * parses the rdata of the Net_DNS2_Packet object
190
+ *
191
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
192
+ *
193
+ * @return boolean
194
+ * @access protected
195
+ *
196
+ */
197
+ protected function rrSet(Net_DNS2_Packet &$packet)
198
+ {
199
+ //
200
+ // parse out the TTL value
201
+ //
202
+ $x = unpack('Cextended/Cversion/Cdo/Cz', pack('N', $this->ttl));
203
+
204
+ $this->extended_rcode = $x['extended'];
205
+ $this->version = $x['version'];
206
+ $this->do = ($x['do'] >> 7);
207
+ $this->z = $x['z'];
208
+
209
+ //
210
+ // parse the data, if there is any
211
+ //
212
+ if ($this->rdlength > 0) {
213
+
214
+ //
215
+ // unpack the code and length
216
+ //
217
+ $x = unpack('noption_code/noption_length', $this->rdata);
218
+
219
+ $this->option_code = $x['option_code'];
220
+ $this->option_length = $x['option_length'];
221
+
222
+ //
223
+ // copy out the data based on the length
224
+ //
225
+ $this->option_data = substr($this->rdata, 4);
226
+ }
227
+
228
+ return true;
229
+ }
230
+
231
+ /**
232
+ * pre-builds the TTL value for this record; we needed to separate this out
233
+ * from the rrGet() function, as the logic in the Net_DNS2_RR packs the TTL
234
+ * value before it builds the rdata value.
235
+ *
236
+ * @return void
237
+ * @access protected
238
+ *
239
+ */
240
+ protected function preBuild()
241
+ {
242
+ //
243
+ // build the TTL value based on the local values
244
+ //
245
+ $ttl = unpack(
246
+ 'N',
247
+ pack('CCCC', $this->extended_rcode, $this->version, ($this->do << 7), 0)
248
+ );
249
+
250
+ $this->ttl = $ttl[1];
251
+
252
+ return;
253
+ }
254
+
255
+ /**
256
+ * returns the rdata portion of the DNS packet
257
+ *
258
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
259
+ * compressed names
260
+ *
261
+ * @return mixed either returns a binary packed
262
+ * string or null on failure
263
+ * @access protected
264
+ *
265
+ */
266
+ protected function rrGet(Net_DNS2_Packet &$packet)
267
+ {
268
+ //
269
+ // if there is an option code, then pack that data too
270
+ //
271
+ if ($this->option_code) {
272
+
273
+ $data = pack('nn', $this->option_code, $this->option_length) .
274
+ $this->option_data;
275
+
276
+ $packet->offset += strlen($data);
277
+
278
+ return $data;
279
+ }
280
+
281
+ return null;
282
+ }
283
+ }
284
+
285
+ /*
286
+ * Local variables:
287
+ * tab-width: 4
288
+ * c-basic-offset: 4
289
+ * c-hanging-comment-ender-p: nil
290
+ * End:
291
+ */
292
+ ?>
includes/Net/DNS2/RR/PTR.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * PTR Resource Record - RFC1035 section 3.3.12
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * / PTRDNAME /
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ *
59
+ * @category Networking
60
+ * @package Net_DNS2
61
+ * @author Mike Pultz <mike@mikepultz.com>
62
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
63
+ * @link http://pear.php.net/package/Net_DNS2
64
+ * @see Net_DNS2_RR
65
+ *
66
+ */
67
+ class Net_DNS2_RR_PTR extends Net_DNS2_RR
68
+ {
69
+ /*
70
+ * the hostname of the PTR entry
71
+ */
72
+ public $ptrdname;
73
+
74
+ /**
75
+ * method to return the rdata portion of the packet as a string
76
+ *
77
+ * @return string
78
+ * @access protected
79
+ *
80
+ */
81
+ protected function rrToString()
82
+ {
83
+ return rtrim($this->ptrdname, '.') . '.';
84
+ }
85
+
86
+ /**
87
+ * parses the rdata portion from a standard DNS config line
88
+ *
89
+ * @param array $rdata a string split line of values for the rdata
90
+ *
91
+ * @return boolean
92
+ * @access protected
93
+ *
94
+ */
95
+ protected function rrFromString(array $rdata)
96
+ {
97
+ $this->ptrdname = rtrim(implode(' ', $rdata), '.');
98
+ return true;
99
+ }
100
+
101
+ /**
102
+ * parses the rdata of the Net_DNS2_Packet object
103
+ *
104
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
105
+ *
106
+ * @return boolean
107
+ * @access protected
108
+ *
109
+ */
110
+ protected function rrSet(Net_DNS2_Packet &$packet)
111
+ {
112
+ if ($this->rdlength > 0) {
113
+
114
+ $offset = $packet->offset;
115
+ $this->ptrdname = Net_DNS2_Packet::expand($packet, $offset);
116
+
117
+ return true;
118
+ }
119
+
120
+ return false;
121
+ }
122
+
123
+ /**
124
+ * returns the rdata portion of the DNS packet
125
+ *
126
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
127
+ * compressed names
128
+ *
129
+ * @return mixed either returns a binary packed
130
+ * string or null on failure
131
+ * @access protected
132
+ *
133
+ */
134
+ protected function rrGet(Net_DNS2_Packet &$packet)
135
+ {
136
+ if (strlen($this->ptrdname) > 0) {
137
+
138
+ return $packet->compress($this->ptrdname, $packet->offset);
139
+ }
140
+
141
+ return null;
142
+ }
143
+ }
144
+
145
+ /*
146
+ * Local variables:
147
+ * tab-width: 4
148
+ * c-basic-offset: 4
149
+ * c-hanging-comment-ender-p: nil
150
+ * End:
151
+ */
152
+ ?>
includes/Net/DNS2/RR/PX.php ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * PX Resource Record - RFC2163 section 4
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | PREFERENCE |
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * / MAP822 /
59
+ * / /
60
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
61
+ * / MAPX400 /
62
+ * / /
63
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--
64
+ *
65
+ * @category Networking
66
+ * @package Net_DNS2
67
+ * @author Mike Pultz <mike@mikepultz.com>
68
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
69
+ * @link http://pear.php.net/package/Net_DNS2
70
+ * @see Net_DNS2_RR
71
+ *
72
+ */
73
+ class Net_DNS2_RR_PX extends Net_DNS2_RR
74
+ {
75
+ /*
76
+ * preference
77
+ */
78
+ public $preference;
79
+
80
+ /*
81
+ * the RFC822 part of the MCGAM
82
+ */
83
+ public $map822;
84
+
85
+ /*
86
+ * the X.400 part of the MCGAM
87
+ */
88
+ public $mapx400;
89
+
90
+ /**
91
+ * method to return the rdata portion of the packet as a string
92
+ *
93
+ * @return string
94
+ * @access protected
95
+ *
96
+ */
97
+ protected function rrToString()
98
+ {
99
+ return $this->preference . ' ' . $this->cleanString($this->map822) . '. ' .
100
+ $this->cleanString($this->mapx400) . '.';
101
+ }
102
+
103
+ /**
104
+ * parses the rdata portion from a standard DNS config line
105
+ *
106
+ * @param array $rdata a string split line of values for the rdata
107
+ *
108
+ * @return boolean
109
+ * @access protected
110
+ *
111
+ */
112
+ protected function rrFromString(array $rdata)
113
+ {
114
+ $this->preference = $rdata[0];
115
+ $this->map822 = $this->cleanString($rdata[1]);
116
+ $this->mapx400 = $this->cleanString($rdata[2]);
117
+
118
+ return true;
119
+ }
120
+
121
+ /**
122
+ * parses the rdata of the Net_DNS2_Packet object
123
+ *
124
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
125
+ *
126
+ * @return boolean
127
+ * @access protected
128
+ *
129
+ */
130
+ protected function rrSet(Net_DNS2_Packet &$packet)
131
+ {
132
+ if ($this->rdlength > 0) {
133
+
134
+ //
135
+ // parse the preference
136
+ //
137
+ $x = unpack('npreference', $this->rdata);
138
+ $this->preference = $x['preference'];
139
+
140
+ $offset = $packet->offset + 2;
141
+
142
+ $this->map822 = Net_DNS2_Packet::expand($packet, $offset);
143
+ $this->mapx400 = Net_DNS2_Packet::expand($packet, $offset);
144
+
145
+ return true;
146
+ }
147
+
148
+ return false;
149
+ }
150
+
151
+ /**
152
+ * returns the rdata portion of the DNS packet
153
+ *
154
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
155
+ * compressed names
156
+ *
157
+ * @return mixed either returns a binary packed
158
+ * string or null on failure
159
+ * @access protected
160
+ *
161
+ */
162
+ protected function rrGet(Net_DNS2_Packet &$packet)
163
+ {
164
+ if (strlen($this->map822) > 0) {
165
+
166
+ $data = pack('n', $this->preference);
167
+ $packet->offset += 2;
168
+
169
+ $data .= $packet->compress($this->map822, $packet->offset);
170
+ $data .= $packet->compress($this->mapx400, $packet->offset);
171
+
172
+ return $data;
173
+ }
174
+
175
+ return null;
176
+ }
177
+ }
178
+
179
+ /*
180
+ * Local variables:
181
+ * tab-width: 4
182
+ * c-basic-offset: 4
183
+ * c-hanging-comment-ender-p: nil
184
+ * End:
185
+ */
186
+ ?>
includes/Net/DNS2/RR/RP.php ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * RP Resource Record - RFC1183 section 2.2
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * / mboxdname /
57
+ * / /
58
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
59
+ * / txtdname /
60
+ * / /
61
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
62
+ *
63
+ * @category Networking
64
+ * @package Net_DNS2
65
+ * @author Mike Pultz <mike@mikepultz.com>
66
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
67
+ * @link http://pear.php.net/package/Net_DNS2
68
+ * @see Net_DNS2_RR
69
+ *
70
+ */
71
+ class Net_DNS2_RR_RP extends Net_DNS2_RR
72
+ {
73
+ /*
74
+ * mailbox for the responsible person
75
+ */
76
+ public $mboxdname;
77
+
78
+ /*
79
+ * is a domain name for which TXT RR's exists
80
+ */
81
+ public $txtdname;
82
+
83
+ /**
84
+ * method to return the rdata portion of the packet as a string
85
+ *
86
+ * @return string
87
+ * @access protected
88
+ *
89
+ */
90
+ protected function rrToString()
91
+ {
92
+ return $this->cleanString($this->mboxdname) . '. ' .
93
+ $this->cleanString($this->txtdname) . '.';
94
+ }
95
+
96
+ /**
97
+ * parses the rdata portion from a standard DNS config line
98
+ *
99
+ * @param array $rdata a string split line of values for the rdata
100
+ *
101
+ * @return boolean
102
+ * @access protected
103
+ *
104
+ */
105
+ protected function rrFromString(array $rdata)
106
+ {
107
+ $this->mboxdname = $this->cleanString($rdata[0]);
108
+ $this->txtdname = $this->cleanString($rdata[1]);
109
+
110
+ return true;
111
+ }
112
+
113
+ /**
114
+ * parses the rdata of the Net_DNS2_Packet object
115
+ *
116
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
117
+ *
118
+ * @return boolean
119
+ * @access protected
120
+ *
121
+ */
122
+ protected function rrSet(Net_DNS2_Packet &$packet)
123
+ {
124
+ if ($this->rdlength > 0) {
125
+
126
+ $offset = $packet->offset;
127
+
128
+ $this->mboxdname = Net_DNS2_Packet::expand($packet, $offset);
129
+ $this->txtdname = Net_DNS2_Packet::expand($packet, $offset);
130
+
131
+ return true;
132
+ }
133
+
134
+ return false;
135
+ }
136
+
137
+ /**
138
+ * returns the rdata portion of the DNS packet
139
+ *
140
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
141
+ * compressed names
142
+ *
143
+ * @return mixed either returns a binary packed
144
+ * string or null on failure
145
+ * @access protected
146
+ *
147
+ */
148
+ protected function rrGet(Net_DNS2_Packet &$packet)
149
+ {
150
+ if (strlen($this->mboxdname) > 0) {
151
+
152
+ return $packet->compress($this->mboxdname, $packet->offset) .
153
+ $packet->compress($this->txtdname, $packet->offset);
154
+ }
155
+
156
+ return null;
157
+ }
158
+ }
159
+
160
+ /*
161
+ * Local variables:
162
+ * tab-width: 4
163
+ * c-basic-offset: 4
164
+ * c-hanging-comment-ender-p: nil
165
+ * End:
166
+ */
167
+ ?>
includes/Net/DNS2/RR/RRSIG.php ADDED
@@ -0,0 +1,329 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ * This file contains code based off the Net::DNS::SEC Perl module by
51
+ * Olaf M. Kolkman
52
+ *
53
+ * This is the copyright notice from the PERL Net::DNS::SEC module:
54
+ *
55
+ * Copyright (c) 2001 - 2005 RIPE NCC. Author Olaf M. Kolkman
56
+ * Copyright (c) 2007 - 2008 NLnet Labs. Author Olaf M. Kolkman
57
+ * <olaf@net-dns.org>
58
+ *
59
+ * All Rights Reserved
60
+ *
61
+ * Permission to use, copy, modify, and distribute this software and its
62
+ * documentation for any purpose and without fee is hereby granted,
63
+ * provided that the above copyright notice appear in all copies and that
64
+ * both that copyright notice and this permission notice appear in
65
+ * supporting documentation, and that the name of the author not be
66
+ * used in advertising or publicity pertaining to distribution of the
67
+ * software without specific, written prior permission.
68
+ *
69
+ * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
70
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
71
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
72
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
73
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
74
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
75
+ *
76
+ */
77
+
78
+ /**
79
+ * RRSIG Resource Record - RFC4034 sction 3.1
80
+ *
81
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
82
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
83
+ * | Type Covered | Algorithm | Labels |
84
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
85
+ * | Original TTL |
86
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
87
+ * | Signature Expiration |
88
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
89
+ * | Signature Inception |
90
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
91
+ * | Key Tag | /
92
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Signer's Name /
93
+ * / /
94
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
95
+ * / /
96
+ * / Signature /
97
+ * / /
98
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99
+ *
100
+ * @category Networking
101
+ * @package Net_DNS2
102
+ * @author Mike Pultz <mike@mikepultz.com>
103
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
104
+ * @link http://pear.php.net/package/Net_DNS2
105
+ * @see Net_DNS2_RR
106
+ *
107
+ */
108
+ class Net_DNS2_RR_RRSIG extends Net_DNS2_RR
109
+ {
110
+ /*
111
+ * the RR type covered by this signature
112
+ */
113
+ public $typecovered;
114
+
115
+ /*
116
+ * the algorithm used for the signature
117
+ */
118
+ public $algorithm;
119
+
120
+ /*
121
+ * the number of labels in the name
122
+ */
123
+ public $labels;
124
+
125
+ /*
126
+ * the original TTL
127
+ */
128
+ public $origttl;
129
+
130
+ /*
131
+ * the signature expiration
132
+ */
133
+ public $sigexp;
134
+
135
+ /*
136
+ * the inception of the signature
137
+ */
138
+ public $sigincep;
139
+
140
+ /*
141
+ * the keytag used
142
+ */
143
+ public $keytag;
144
+
145
+ /*
146
+ * the signer's name
147
+ */
148
+ public $signname;
149
+
150
+ /*
151
+ * the signature
152
+ */
153
+ public $signature;
154
+
155
+ /**
156
+ * method to return the rdata portion of the packet as a string
157
+ *
158
+ * @return string
159
+ * @access protected
160
+ *
161
+ */
162
+ protected function rrToString()
163
+ {
164
+ return $this->typecovered . ' ' . $this->algorithm . ' ' .
165
+ $this->labels . ' ' . $this->origttl . ' ' .
166
+ $this->sigexp . ' ' . $this->sigincep . ' ' .
167
+ $this->keytag . ' ' . $this->cleanString($this->signname) . '. ' .
168
+ $this->signature;
169
+ }
170
+
171
+ /**
172
+ * parses the rdata portion from a standard DNS config line
173
+ *
174
+ * @param array $rdata a string split line of values for the rdata
175
+ *
176
+ * @return boolean
177
+ * @access protected
178
+ *
179
+ */
180
+ protected function rrFromString(array $rdata)
181
+ {
182
+ $this->typecovered = strtoupper(array_shift($rdata));
183
+ $this->algorithm = array_shift($rdata);
184
+ $this->labels = array_shift($rdata);
185
+ $this->origttl = array_shift($rdata);
186
+ $this->sigexp = array_shift($rdata);
187
+ $this->sigincep = array_shift($rdata);
188
+ $this->keytag = array_shift($rdata);
189
+ $this->signname = $this->cleanString(array_shift($rdata));
190
+
191
+ foreach ($rdata as $line) {
192
+
193
+ $this->signature .= $line;
194
+ }
195
+
196
+ $this->signature = trim($this->signature);
197
+
198
+ return true;
199
+ }
200
+
201
+ /**
202
+ * parses the rdata of the Net_DNS2_Packet object
203
+ *
204
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
205
+ *
206
+ * @return boolean
207
+ * @access protected
208
+ *
209
+ */
210
+ protected function rrSet(Net_DNS2_Packet &$packet)
211
+ {
212
+ if ($this->rdlength > 0) {
213
+
214
+ //
215
+ // unpack
216
+ //
217
+ $x = unpack(
218
+ 'ntc/Calgorithm/Clabels/Norigttl/Nsigexp/Nsigincep/nkeytag',
219
+ $this->rdata
220
+ );
221
+
222
+ $this->typecovered = Net_DNS2_Lookups::$rr_types_by_id[$x['tc']];
223
+ $this->algorithm = $x['algorithm'];
224
+ $this->labels = $x['labels'];
225
+ $this->origttl = Net_DNS2::expandUint32($x['origttl']);
226
+
227
+ //
228
+ // the dates are in GM time
229
+ //
230
+ $this->sigexp = gmdate('YmdHis', $x['sigexp']);
231
+ $this->sigincep = gmdate('YmdHis', $x['sigincep']);
232
+
233
+ //
234
+ // get the keytag
235
+ //
236
+ $this->keytag = $x['keytag'];
237
+
238
+ //
239
+ // get teh signers name and signature
240
+ //
241
+ $offset = $packet->offset + 18;
242
+ $sigoffset = $offset;
243
+
244
+ $this->signname = strtolower(
245
+ Net_DNS2_Packet::expand($packet, $sigoffset)
246
+ );
247
+ $this->signature = base64_encode(
248
+ substr($this->rdata, 18 + ($sigoffset - $offset))
249
+ );
250
+
251
+ return true;
252
+ }
253
+
254
+ return false;
255
+ }
256
+
257
+ /**
258
+ * returns the rdata portion of the DNS packet
259
+ *
260
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
261
+ * compressed names
262
+ *
263
+ * @return mixed either returns a binary packed
264
+ * string or null on failure
265
+ * @access protected
266
+ *
267
+ */
268
+ protected function rrGet(Net_DNS2_Packet &$packet)
269
+ {
270
+ if (strlen($this->signature) > 0) {
271
+
272
+ //
273
+ // parse the values out of the dates
274
+ //
275
+ preg_match(
276
+ '/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/', $this->sigexp, $e
277
+ );
278
+ preg_match(
279
+ '/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/', $this->sigincep, $i
280
+ );
281
+
282
+ //
283
+ // pack the value
284
+ //
285
+ $data = pack(
286
+ 'nCCNNNn',
287
+ Net_DNS2_Lookups::$rr_types_by_name[$this->typecovered],
288
+ $this->algorithm,
289
+ $this->labels,
290
+ $this->origttl,
291
+ gmmktime($e[4], $e[5], $e[6], $e[2], $e[3], $e[1]),
292
+ gmmktime($i[4], $i[5], $i[6], $i[2], $i[3], $i[1]),
293
+ $this->keytag
294
+ );
295
+
296
+ //
297
+ // the signer name is special; it's not allowed to be compressed
298
+ // (see section 3.1.7)
299
+ //
300
+ $names = explode('.', strtolower($this->signname));
301
+ foreach ($names as $name) {
302
+
303
+ $data .= chr(strlen($name));
304
+ $data .= $name;
305
+ }
306
+ $data .= "\0";
307
+
308
+ //
309
+ // add the signature
310
+ //
311
+ $data .= base64_decode($this->signature);
312
+
313
+ $packet->offset += strlen($data);
314
+
315
+ return $data;
316
+ }
317
+
318
+ return null;
319
+ }
320
+ }
321
+
322
+ /*
323
+ * Local variables:
324
+ * tab-width: 4
325
+ * c-basic-offset: 4
326
+ * c-hanging-comment-ender-p: nil
327
+ * End:
328
+ */
329
+ ?>
includes/Net/DNS2/RR/RT.php ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * RT Resource Record - RFC1183 section 3.3
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | preference |
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * / intermediate-host /
59
+ * / /
60
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
61
+ *
62
+ * @category Networking
63
+ * @package Net_DNS2
64
+ * @author Mike Pultz <mike@mikepultz.com>
65
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
66
+ * @link http://pear.php.net/package/Net_DNS2
67
+ * @see Net_DNS2_RR
68
+ *
69
+ */
70
+ class Net_DNS2_RR_RT extends Net_DNS2_RR
71
+ {
72
+ /*
73
+ * the preference of this route
74
+ */
75
+ public $preference;
76
+
77
+ /*
78
+ * host which will servce as an intermediate in reaching the owner host
79
+ */
80
+ public $intermediatehost;
81
+
82
+ /**
83
+ * method to return the rdata portion of the packet as a string
84
+ *
85
+ * @return string
86
+ * @access protected
87
+ *
88
+ */
89
+ protected function rrToString()
90
+ {
91
+ return $this->preference . ' ' .
92
+ $this->cleanString($this->intermediatehost) . '.';
93
+ }
94
+
95
+ /**
96
+ * parses the rdata portion from a standard DNS config line
97
+ *
98
+ * @param array $rdata a string split line of values for the rdata
99
+ *
100
+ * @return boolean
101
+ * @access protected
102
+ *
103
+ */
104
+ protected function rrFromString(array $rdata)
105
+ {
106
+ $this->preference = $rdata[0];
107
+ $this->intermediatehost = $this->cleanString($rdata[1]);
108
+
109
+ return true;
110
+ }
111
+
112
+ /**
113
+ * parses the rdata of the Net_DNS2_Packet object
114
+ *
115
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
116
+ *
117
+ * @return boolean
118
+ * @access protected
119
+ *
120
+ */
121
+ protected function rrSet(Net_DNS2_Packet &$packet)
122
+ {
123
+ if ($this->rdlength > 0) {
124
+
125
+ //
126
+ // unpack the preference
127
+ //
128
+ $x = unpack('npreference', $this->rdata);
129
+
130
+ $this->preference = $x['preference'];
131
+ $offset = $packet->offset + 2;
132
+
133
+ $this->intermediatehost = Net_DNS2_Packet::expand($packet, $offset);
134
+
135
+ return true;
136
+ }
137
+
138
+ return false;
139
+ }
140
+
141
+ /**
142
+ * returns the rdata portion of the DNS packet
143
+ *
144
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
145
+ * compressed names
146
+ *
147
+ * @return mixed either returns a binary packed
148
+ * string or null on failure
149
+ * @access protected
150
+ *
151
+ */
152
+ protected function rrGet(Net_DNS2_Packet &$packet)
153
+ {
154
+ if (strlen($this->intermediatehost) > 0) {
155
+
156
+ $data = pack('n', $this->preference);
157
+ $packet->offset += 2;
158
+
159
+ $data .= $packet->compress($this->intermediatehost, $packet->offset);
160
+
161
+ return $data;
162
+ }
163
+
164
+ return null;
165
+ }
166
+ }
167
+
168
+ /*
169
+ * Local variables:
170
+ * tab-width: 4
171
+ * c-basic-offset: 4
172
+ * c-hanging-comment-ender-p: nil
173
+ * End:
174
+ */
175
+ ?>
includes/Net/DNS2/RR/SIG.php ADDED
@@ -0,0 +1,459 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ * This file contains code based off the Net::DNS::SEC Perl module by
51
+ * Olaf M. Kolkman
52
+ *
53
+ * This is the copyright notice from the PERL Net::DNS::SEC module:
54
+ *
55
+ * Copyright (c) 2001 - 2005 RIPE NCC. Author Olaf M. Kolkman
56
+ * Copyright (c) 2007 - 2008 NLnet Labs. Author Olaf M. Kolkman
57
+ * <olaf@net-dns.org>
58
+ *
59
+ * All Rights Reserved
60
+ *
61
+ * Permission to use, copy, modify, and distribute this software and its
62
+ * documentation for any purpose and without fee is hereby granted,
63
+ * provided that the above copyright notice appear in all copies and that
64
+ * both that copyright notice and this permission notice appear in
65
+ * supporting documentation, and that the name of the author not be
66
+ * used in advertising or publicity pertaining to distribution of the
67
+ * software without specific, written prior permission.
68
+ *
69
+ * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
70
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
71
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
72
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
73
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
74
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
75
+ *
76
+ */
77
+
78
+ /**
79
+ * SIG Resource Record - RFC2535 section 4.1
80
+ *
81
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
82
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
83
+ * | Type Covered | Algorithm | Labels |
84
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
85
+ * | Original TTL |
86
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
87
+ * | Signature Expiration |
88
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
89
+ * | Signature Inception |
90
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
91
+ * | Key Tag | /
92
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Signer's Name /
93
+ * / /
94
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
95
+ * / /
96
+ * / Signature /
97
+ * / /
98
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99
+ *
100
+ * @category Networking
101
+ * @package Net_DNS2
102
+ * @author Mike Pultz <mike@mikepultz.com>
103
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
104
+ * @link http://pear.php.net/package/Net_DNS2
105
+ * @see Net_DNS2_RR
106
+ *
107
+ */
108
+ class Net_DNS2_RR_SIG extends Net_DNS2_RR
109
+ {
110
+ /*
111
+ * and instance of a Net_DNS2_PrivateKey object
112
+ */
113
+ public $private_key = null;
114
+
115
+ /*
116
+ * the RR type covered by this signature
117
+ */
118
+ public $typecovered;
119
+
120
+ /*
121
+ * the algorithm used for the signature
122
+ */
123
+ public $algorithm;
124
+
125
+ /*
126
+ * the number of labels in the name
127
+ */
128
+ public $labels;
129
+
130
+ /*
131
+ * the original TTL
132
+ */
133
+ public $origttl;
134
+
135
+ /*
136
+ * the signature expiration
137
+ */
138
+ public $sigexp;
139
+
140
+ /*
141
+ * the inception of the signature
142
+ */
143
+ public $sigincep;
144
+
145
+ /*
146
+ * the keytag used
147
+ */
148
+ public $keytag;
149
+
150
+ /*
151
+ * the signer's name
152
+ */
153
+ public $signname;
154
+
155
+ /*
156
+ * the signature
157
+ */
158
+ public $signature;
159
+
160
+ /**
161
+ * method to return the rdata portion of the packet as a string
162
+ *
163
+ * @return string
164
+ * @access protected
165
+ *
166
+ */
167
+ protected function rrToString()
168
+ {
169
+ return $this->typecovered . ' ' . $this->algorithm . ' ' .
170
+ $this->labels . ' ' . $this->origttl . ' ' .
171
+ $this->sigexp . ' ' . $this->sigincep . ' ' .
172
+ $this->keytag . ' ' . $this->cleanString($this->signname) . '. ' .
173
+ $this->signature;
174
+ }
175
+
176
+ /**
177
+ * parses the rdata portion from a standard DNS config line
178
+ *
179
+ * @param array $rdata a string split line of values for the rdata
180
+ *
181
+ * @return boolean
182
+ * @access protected
183
+ *
184
+ */
185
+ protected function rrFromString(array $rdata)
186
+ {
187
+ $this->typecovered = strtoupper(array_shift($rdata));
188
+ $this->algorithm = array_shift($rdata);
189
+ $this->labels = array_shift($rdata);
190
+ $this->origttl = array_shift($rdata);
191
+ $this->sigexp = array_shift($rdata);
192
+ $this->sigincep = array_shift($rdata);
193
+ $this->keytag = array_shift($rdata);
194
+ $this->signname = $this->cleanString(array_shift($rdata));
195
+
196
+ foreach ($rdata as $line) {
197
+
198
+ $this->signature .= $line;
199
+ }
200
+
201
+ $this->signature = trim($this->signature);
202
+
203
+ return true;
204
+ }
205
+
206
+ /**
207
+ * parses the rdata of the Net_DNS2_Packet object
208
+ *
209
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
210
+ *
211
+ * @return boolean
212
+ * @access protected
213
+ *
214
+ */
215
+ protected function rrSet(Net_DNS2_Packet &$packet)
216
+ {
217
+ if ($this->rdlength > 0) {
218
+
219
+ //
220
+ // unpack
221
+ //
222
+ $x = unpack(
223
+ 'ntc/Calgorithm/Clabels/Norigttl/Nsigexp/Nsigincep/nkeytag',
224
+ $this->rdata
225
+ );
226
+
227
+ $this->typecovered = Net_DNS2_Lookups::$rr_types_by_id[$x['tc']];
228
+ $this->algorithm = $x['algorithm'];
229
+ $this->labels = $x['labels'];
230
+ $this->origttl = Net_DNS2::expandUint32($x['origttl']);
231
+
232
+ //
233
+ // the dates are in GM time
234
+ //
235
+ $this->sigexp = gmdate('YmdHis', $x['sigexp']);
236
+ $this->sigincep = gmdate('YmdHis', $x['sigincep']);
237
+
238
+ //
239
+ // get the keytag
240
+ //
241
+ $this->keytag = $x['keytag'];
242
+
243
+ //
244
+ // get teh signers name and signature
245
+ //
246
+ $offset = $packet->offset + 18;
247
+ $sigoffset = $offset;
248
+
249
+ $this->signname = strtolower(
250
+ Net_DNS2_Packet::expand($packet, $sigoffset)
251
+ );
252
+ $this->signature = base64_encode(
253
+ substr($this->rdata, 18 + ($sigoffset - $offset))
254
+ );
255
+
256
+ return true;
257
+ }
258
+
259
+ return false;
260
+ }
261
+
262
+ /**
263
+ * returns the rdata portion of the DNS packet
264
+ *
265
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
266
+ * compressed names
267
+ *
268
+ * @return mixed either returns a binary packed
269
+ * string or null on failure
270
+ * @access protected
271
+ *
272
+ */
273
+ protected function rrGet(Net_DNS2_Packet &$packet)
274
+ {
275
+ //
276
+ // parse the values out of the dates
277
+ //
278
+ preg_match(
279
+ '/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/', $this->sigexp, $e
280
+ );
281
+ preg_match(
282
+ '/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/', $this->sigincep, $i
283
+ );
284
+
285
+ //
286
+ // pack the value
287
+ //
288
+ $data = pack(
289
+ 'nCCNNNn',
290
+ Net_DNS2_Lookups::$rr_types_by_name[$this->typecovered],
291
+ $this->algorithm,
292
+ $this->labels,
293
+ $this->origttl,
294
+ gmmktime($e[4], $e[5], $e[6], $e[2], $e[3], $e[1]),
295
+ gmmktime($i[4], $i[5], $i[6], $i[2], $i[3], $i[1]),
296
+ $this->keytag
297
+ );
298
+
299
+ //
300
+ // the signer name is special; it's not allowed to be compressed
301
+ // (see section 3.1.7)
302
+ //
303
+ $names = explode('.', strtolower($this->signname));
304
+ foreach ($names as $name) {
305
+
306
+ $data .= chr(strlen($name));
307
+ $data .= $name;
308
+ }
309
+
310
+ $data .= chr('0');
311
+
312
+ //
313
+ // if the signature is empty, and $this->private_key is an instance of a
314
+ // private key object, and we have access to openssl, then assume this
315
+ // is a SIG(0), and generate a new signature
316
+ //
317
+ if ( (strlen($this->signature) == 0)
318
+ && ($this->private_key instanceof Net_DNS2_PrivateKey)
319
+ && (extension_loaded('openssl') === true)
320
+ ) {
321
+
322
+ //
323
+ // create a new packet for the signature-
324
+ //
325
+ $new_packet = new Net_DNS2_Packet_Request('example.com', 'SOA', 'IN');
326
+
327
+ //
328
+ // copy the packet data over
329
+ //
330
+ $new_packet->copy($packet);
331
+
332
+ //
333
+ // remove the SIG object from the additional list
334
+ //
335
+ array_pop($new_packet->additional);
336
+ $new_packet->header->arcount = count($new_packet->additional);
337
+
338
+ //
339
+ // copy out the data
340
+ //
341
+ $sigdata = $data . $new_packet->get();
342
+
343
+ //
344
+ // based on the algorithm
345
+ //
346
+ $algorithm = 0;
347
+
348
+ switch($this->algorithm) {
349
+
350
+ //
351
+ // MD5
352
+ //
353
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSAMD5:
354
+
355
+ $algorithm = OPENSSL_ALGO_MD5;
356
+ break;
357
+
358
+ //
359
+ // SHA1
360
+ //
361
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA1:
362
+
363
+ $algorithm = OPENSSL_ALGO_SHA1;
364
+ break;
365
+
366
+ //
367
+ // SHA256 (PHP 5.4.8 or higher)
368
+ //
369
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA256:
370
+
371
+ if (version_compare(PHP_VERSION, '5.4.8', '<') == true) {
372
+
373
+ throw new Net_DNS2_Exception(
374
+ 'SHA256 support is only available in PHP >= 5.4.8',
375
+ Net_DNS2_Lookups::E_OPENSSL_INV_ALGO
376
+ );
377
+ }
378
+
379
+ $algorithm = OPENSSL_ALGO_SHA256;
380
+ break;
381
+
382
+ //
383
+ // SHA512 (PHP 5.4.8 or higher)
384
+ //
385
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA512:
386
+
387
+ if (version_compare(PHP_VERSION, '5.4.8', '<') == true) {
388
+
389
+ throw new Net_DNS2_Exception(
390
+ 'SHA512 support is only available in PHP >= 5.4.8',
391
+ Net_DNS2_Lookups::E_OPENSSL_INV_ALGO
392
+ );
393
+ }
394
+
395
+ $algorithm = OPENSSL_ALGO_SHA512;
396
+ break;
397
+
398
+ //
399
+ // unsupported at the moment
400
+ //
401
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_DSA:
402
+ case Net_DNS2_Lookups::DSNSEC_ALGORITHM_RSASHA1NSEC3SHA1:
403
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_DSANSEC3SHA1:
404
+ default:
405
+ throw new Net_DNS2_Exception(
406
+ 'invalid or unsupported algorithm',
407
+ Net_DNS2_Lookups::E_OPENSSL_INV_ALGO
408
+ );
409
+ break;
410
+ }
411
+
412
+ //
413
+ // sign the data
414
+ //
415
+ if (openssl_sign($sigdata, $this->signature, $this->private_key->instance, $algorithm) == false) {
416
+
417
+ throw new Net_DNS2_Exception(
418
+ openssl_error_string(),
419
+ Net_DNS2_Lookups::E_OPENSSL_ERROR
420
+ );
421
+ }
422
+
423
+ //
424
+ // build the signature value based
425
+ //
426
+ switch($this->algorithm) {
427
+
428
+ //
429
+ // RSA- add it directly
430
+ //
431
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSAMD5:
432
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA1:
433
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA256:
434
+ case Net_DNS2_Lookups::DNSSEC_ALGORITHM_RSASHA512:
435
+
436
+ $this->signature = base64_encode($this->signature);
437
+ break;
438
+ }
439
+ }
440
+
441
+ //
442
+ // add the signature
443
+ //
444
+ $data .= base64_decode($this->signature);
445
+
446
+ $packet->offset += strlen($data);
447
+
448
+ return $data;
449
+ }
450
+ }
451
+
452
+ /*
453
+ * Local variables:
454
+ * tab-width: 4
455
+ * c-basic-offset: 4
456
+ * c-hanging-comment-ender-p: nil
457
+ * End:
458
+ */
459
+ ?>
includes/Net/DNS2/RR/SOA.php ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * SOA Resource Record - RFC1035 section 3.3.13
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * / MNAME /
57
+ * / /
58
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
59
+ * / RNAME /
60
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
61
+ * | SERIAL |
62
+ * | |
63
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
64
+ * | REFRESH |
65
+ * | |
66
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
67
+ * | RETRY |
68
+ * | |
69
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
70
+ * | EXPIRE |
71
+ * | |
72
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
73
+ * | MINIMUM |
74
+ * | |
75
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
76
+ *
77
+ * @category Networking
78
+ * @package Net_DNS2
79
+ * @author Mike Pultz <mike@mikepultz.com>
80
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
81
+ * @link http://pear.php.net/package/Net_DNS2
82
+ * @see Net_DNS2_RR
83
+ *
84
+ */
85
+ class Net_DNS2_RR_SOA extends Net_DNS2_RR
86
+ {
87
+ /*
88
+ * The master DNS server
89
+ */
90
+ public $mname;
91
+
92
+ /*
93
+ * mailbox of the responsible person
94
+ */
95
+ public $rname;
96
+
97
+ /*
98
+ * serial number
99
+ */
100
+ public $serial;
101
+
102
+ /*
103
+ * refresh time
104
+ */
105
+ public $refresh;
106
+
107
+ /*
108
+ * retry interval
109
+ */
110
+ public $retry;
111
+
112
+ /*
113
+ * expire time
114
+ */
115
+ public $expire;
116
+
117
+ /*
118
+ * minimum TTL for any RR in this zone
119
+ */
120
+ public $minimum;
121
+
122
+ /**
123
+ * method to return the rdata portion of the packet as a string
124
+ *
125
+ * @return string
126
+ * @access protected
127
+ *
128
+ */
129
+ protected function rrToString()
130
+ {
131
+ return $this->cleanString($this->mname) . '. ' .
132
+ $this->cleanString($this->rname) . '. ' .
133
+ $this->serial . ' ' . $this->refresh . ' ' . $this->retry . ' ' .
134
+ $this->expire . ' ' . $this->minimum;
135
+ }
136
+
137
+ /**
138
+ * parses the rdata portion from a standard DNS config line
139
+ *
140
+ * @param array $rdata a string split line of values for the rdata
141
+ *
142
+ * @return boolean
143
+ * @access protected
144
+ *
145
+ */
146
+ protected function rrFromString(array $rdata)
147
+ {
148
+ $this->mname = $this->cleanString($rdata[0]);
149
+ $this->rname = $this->cleanString($rdata[1]);
150
+
151
+ $this->serial = $rdata[2];
152
+ $this->refresh = $rdata[3];
153
+ $this->retry = $rdata[4];
154
+ $this->expire = $rdata[5];
155
+ $this->minimum = $rdata[6];
156
+
157
+ return true;
158
+ }
159
+
160
+ /**
161
+ * parses the rdata of the Net_DNS2_Packet object
162
+ *
163
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
164
+ *
165
+ * @return boolean
166
+ * @access protected
167
+ *
168
+ */
169
+ protected function rrSet(Net_DNS2_Packet &$packet)
170
+ {
171
+ if ($this->rdlength > 0) {
172
+
173
+ //
174
+ // parse the
175
+ //
176
+ $offset = $packet->offset;
177
+
178
+ $this->mname = Net_DNS2_Packet::expand($packet, $offset);
179
+ $this->rname = Net_DNS2_Packet::expand($packet, $offset);
180
+
181
+ //
182
+ // get the SOA values
183
+ //
184
+ $x = unpack(
185
+ '@' . $offset . '/Nserial/Nrefresh/Nretry/Nexpire/Nminimum/',
186
+ $packet->rdata
187
+ );
188
+
189
+ $this->serial = Net_DNS2::expandUint32($x['serial']);
190
+ $this->refresh = Net_DNS2::expandUint32($x['refresh']);
191
+ $this->retry = Net_DNS2::expandUint32($x['retry']);
192
+ $this->expire = Net_DNS2::expandUint32($x['expire']);
193
+ $this->minimum = Net_DNS2::expandUint32($x['minimum']);
194
+
195
+ return true;
196
+ }
197
+
198
+ return false;
199
+ }
200
+
201
+ /**
202
+ * returns the rdata portion of the DNS packet
203
+ *
204
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
205
+ * compressed names
206
+ *
207
+ * @return mixed either returns a binary packed
208
+ * string or null on failure
209
+ * @access protected
210
+ *
211
+ */
212
+ protected function rrGet(Net_DNS2_Packet &$packet)
213
+ {
214
+ if (strlen($this->mname) > 0) {
215
+
216
+ $data = $packet->compress($this->mname, $packet->offset);
217
+ $data .= $packet->compress($this->rname, $packet->offset);
218
+
219
+ $data .= pack(
220
+ 'N5', $this->serial, $this->refresh, $this->retry,
221
+ $this->expire, $this->minimum
222
+ );
223
+
224
+ $packet->offset += 20;
225
+
226
+ return $data;
227
+ }
228
+
229
+ return null;
230
+ }
231
+ }
232
+
233
+ /*
234
+ * Local variables:
235
+ * tab-width: 4
236
+ * c-basic-offset: 4
237
+ * c-hanging-comment-ender-p: nil
238
+ * End:
239
+ */
240
+ ?>
includes/Net/DNS2/RR/SPF.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * The SPF RR is implemented exactly like the TXT record, so
54
+ * for now we just extend the TXT RR and use it.
55
+ *
56
+ * @category Networking
57
+ * @package Net_DNS2
58
+ * @author Mike Pultz <mike@mikepultz.com>
59
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
60
+ * @link http://pear.php.net/package/Net_DNS2
61
+ * @see Net_DNS2_RR
62
+ *
63
+ */
64
+ class Net_DNS2_RR_SPF extends Net_DNS2_RR_TXT
65
+ {
66
+ }
67
+
68
+ /*
69
+ * Local variables:
70
+ * tab-width: 4
71
+ * c-basic-offset: 4
72
+ * c-hanging-comment-ender-p: nil
73
+ * End:
74
+ */
75
+ ?>
includes/Net/DNS2/RR/SRV.php ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * SRV Resource Record - RFC2782
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | PRIORITY |
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * | WEIGHT |
59
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
60
+ * | PORT |
61
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
62
+ * / TARGET /
63
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
64
+ *
65
+ * @category Networking
66
+ * @package Net_DNS2
67
+ * @author Mike Pultz <mike@mikepultz.com>
68
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
69
+ * @link http://pear.php.net/package/Net_DNS2
70
+ * @see Net_DNS2_RR
71
+ *
72
+ */
73
+ class Net_DNS2_RR_SRV extends Net_DNS2_RR
74
+ {
75
+ /*
76
+ * The priority of this target host.
77
+ */
78
+ public $priority;
79
+
80
+ /*
81
+ * a relative weight for entries with the same priority
82
+ */
83
+ public $weight;
84
+
85
+ /*
86
+ * The port on this target host of this service.
87
+ */
88
+ public $port;
89
+
90
+ /*
91
+ * The domain name of the target host
92
+ */
93
+ public $target;
94
+
95
+ /**
96
+ * method to return the rdata portion of the packet as a string
97
+ *
98
+ * @return string
99
+ * @access protected
100
+ *
101
+ */
102
+ protected function rrToString()
103
+ {
104
+ return $this->priority . ' ' . $this->weight . ' ' .
105
+ $this->port . ' ' . $this->cleanString($this->target) . '.';
106
+ }
107
+
108
+ /**
109
+ * parses the rdata portion from a standard DNS config line
110
+ *
111
+ * @param array $rdata a string split line of values for the rdata
112
+ *
113
+ * @return boolean
114
+ * @access protected
115
+ *
116
+ */
117
+ protected function rrFromString(array $rdata)
118
+ {
119
+ $this->priority = $rdata[0];
120
+ $this->weight = $rdata[1];
121
+ $this->port = $rdata[2];
122
+
123
+ $this->target = $this->cleanString($rdata[3]);
124
+
125
+ return true;
126
+ }
127
+
128
+ /**
129
+ * parses the rdata of the Net_DNS2_Packet object
130
+ *
131
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
132
+ *
133
+ * @return boolean
134
+ * @access protected
135
+ *
136
+ */
137
+ protected function rrSet(Net_DNS2_Packet &$packet)
138
+ {
139
+ if ($this->rdlength > 0) {
140
+
141
+ //
142
+ // unpack the priority, weight and port
143
+ //
144
+ $x = unpack('npriority/nweight/nport', $this->rdata);
145
+
146
+ $this->priority = $x['priority'];
147
+ $this->weight = $x['weight'];
148
+ $this->port = $x['port'];
149
+
150
+ $offset = $packet->offset + 6;
151
+ $this->target = Net_DNS2_Packet::expand($packet, $offset);
152
+
153
+ return true;
154
+ }
155
+
156
+ return false;
157
+ }
158
+
159
+ /**
160
+ * returns the rdata portion of the DNS packet
161
+ *
162
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
163
+ * compressed names
164
+ *
165
+ * @return mixed either returns a binary packed
166
+ * string or null on failure
167
+ * @access protected
168
+ *
169
+ */
170
+ protected function rrGet(Net_DNS2_Packet &$packet)
171
+ {
172
+ if (strlen($this->target) > 0) {
173
+
174
+ $data = pack('nnn', $this->priority, $this->weight, $this->port);
175
+ $packet->offset += 6;
176
+
177
+ $data .= $packet->compress($this->target, $packet->offset);
178
+
179
+ return $data;
180
+ }
181
+
182
+ return null;
183
+ }
184
+ }
185
+
186
+ ?>
includes/Net/DNS2/RR/SSHFP.php ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * SSHFP Resource Record - RFC4255 section 3.1
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | algorithm | fp type | /
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /
59
+ * / /
60
+ * / fingerprint /
61
+ * / /
62
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
+ *
64
+ * @category Networking
65
+ * @package Net_DNS2
66
+ * @author Mike Pultz <mike@mikepultz.com>
67
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
68
+ * @link http://pear.php.net/package/Net_DNS2
69
+ * @see Net_DNS2_RR
70
+ *
71
+ */
72
+ class Net_DNS2_RR_SSHFP extends Net_DNS2_RR
73
+ {
74
+ /*
75
+ * the algorithm used
76
+ */
77
+ public $algorithm;
78
+
79
+ /*
80
+ * The finger print type
81
+ */
82
+ public $fp_type;
83
+
84
+ /*
85
+ * the finger print data
86
+ */
87
+ public $fingerprint;
88
+
89
+ /*
90
+ * Algorithms
91
+ */
92
+ const SSHFP_ALGORITHM_RES = 0;
93
+ const SSHFP_ALGORITHM_RSA = 1;
94
+ const SSHFP_ALGORITHM_DSS = 2;
95
+
96
+ /*
97
+ * Fingerprint Types
98
+ */
99
+ const SSHFP_FPTYPE_RES = 0;
100
+ const SSHFP_FPTYPE_SHA1 = 1;
101
+
102
+
103
+ /**
104
+ * method to return the rdata portion of the packet as a string
105
+ *
106
+ * @return string
107
+ * @access protected
108
+ *
109
+ */
110
+ protected function rrToString()
111
+ {
112
+ return $this->algorithm . ' ' . $this->fp_type . ' ' . $this->fingerprint;
113
+ }
114
+
115
+ /**
116
+ * parses the rdata portion from a standard DNS config line
117
+ *
118
+ * @param array $rdata a string split line of values for the rdata
119
+ *
120
+ * @return boolean
121
+ * @access protected
122
+ *
123
+ */
124
+ protected function rrFromString(array $rdata)
125
+ {
126
+ //
127
+ // "The use of mnemonics instead of numbers is not allowed."
128
+ //
129
+ // RFC4255 section 3.2
130
+ //
131
+ $algorithm = array_shift($rdata);
132
+ $fp_type = array_shift($rdata);
133
+ $fingerprint = strtolower(implode('', $rdata));
134
+
135
+ //
136
+ // There are only two algorithm's defined
137
+ //
138
+ if ( ($algorithm != self::SSHFP_ALGORITHM_RSA)
139
+ && ($algorithm != self::SSHFP_ALGORITHM_DSS)
140
+ ) {
141
+ return false;
142
+ }
143
+
144
+ //
145
+ // there's only one fingerprint type currently implemented, so if it's not
146
+ // that, then fail.
147
+ //
148
+ if ($fp_type != self::SSHFP_FPTYPE_SHA1) {
149
+ return false;
150
+ }
151
+
152
+ $this->algorithm = $algorithm;
153
+ $this->fp_type = $fp_type;
154
+ $this->fingerprint = $fingerprint;
155
+
156
+ return true;
157
+ }
158
+
159
+ /**
160
+ * parses the rdata of the Net_DNS2_Packet object
161
+ *
162
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
163
+ *
164
+ * @return boolean
165
+ * @access protected
166
+ *
167
+ */
168
+ protected function rrSet(Net_DNS2_Packet &$packet)
169
+ {
170
+ if ($this->rdlength > 0) {
171
+
172
+ //
173
+ // unpack the algorithm and finger print type
174
+ //
175
+ $x = unpack('Calgorithm/Cfp_type', $this->rdata);
176
+
177
+ $this->algorithm = $x['algorithm'];
178
+ $this->fp_type = $x['fp_type'];
179
+
180
+ //
181
+ // There are only two algorithm's defined
182
+ //
183
+ if ( ($this->algorithm != self::SSHFP_ALGORITHM_RSA)
184
+ && ($this->algorithm != self::SSHFP_ALGORITHM_DSS)
185
+ ) {
186
+ return false;
187
+ }
188
+
189
+ //
190
+ // there's only one fingerprint type currently implemented,
191
+ // so if it's not that, then fail.
192
+ //
193
+ if ($this->fp_type != self::SSHFP_FPTYPE_SHA1) {
194
+ return false;
195
+ }
196
+
197
+ //
198
+ // parse the finger print; this assumes SHA-1
199
+ //
200
+ $fp = unpack('H*a', substr($this->rdata, 2));
201
+ $this->fingerprint = strtolower($fp['a']);
202
+
203
+ return true;
204
+ }
205
+
206
+ return false;
207
+ }
208
+
209
+ /**
210
+ * returns the rdata portion of the DNS packet
211
+ *
212
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
213
+ * compressed names
214
+ *
215
+ * @return mixed either returns a binary packed
216
+ * string or null on failure
217
+ * @access protected
218
+ *
219
+ */
220
+ protected function rrGet(Net_DNS2_Packet &$packet)
221
+ {
222
+ if (strlen($this->fingerprint) > 0) {
223
+
224
+ $data = pack(
225
+ 'CCH*', $this->algorithm, $this->fp_type, $this->fingerprint
226
+ );
227
+
228
+ $packet->offset += strlen($data);
229
+
230
+ return $data;
231
+ }
232
+
233
+ return null;
234
+ }
235
+ }
236
+
237
+ /*
238
+ * Local variables:
239
+ * tab-width: 4
240
+ * c-basic-offset: 4
241
+ * c-hanging-comment-ender-p: nil
242
+ * End:
243
+ */
244
+ ?>
includes/Net/DNS2/RR/TA.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2011, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2011 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.2.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * The TA RR is implemented exactly like the DS record, so
54
+ * for now we just extend the DS RR and use it.
55
+ *
56
+ * @category Networking
57
+ * @package Net_DNS2
58
+ * @author Mike Pultz <mike@mikepultz.com>
59
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
60
+ * @link http://pear.php.net/package/Net_DNS2
61
+ * @see Net_DNS2_RR
62
+ *
63
+ */
64
+ class Net_DNS2_RR_TA extends Net_DNS2_RR_DS
65
+ {
66
+ }
67
+
68
+ /*
69
+ * Local variables:
70
+ * tab-width: 4
71
+ * c-basic-offset: 4
72
+ * c-hanging-comment-ender-p: nil
73
+ * End:
74
+ */
75
+ ?>
includes/Net/DNS2/RR/TALINK.php ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2011, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2011 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.2.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * TALINK Resource Record - DNSSEC Trust Anchor
54
+ *
55
+ * http://tools.ietf.org/id/draft-ietf-dnsop-dnssec-trust-history-00.txt
56
+ *
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * / PREVIOUS /
59
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
60
+ * / NEXT /
61
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
62
+ *
63
+ * @category Networking
64
+ * @package Net_DNS2
65
+ * @author Mike Pultz <mike@mikepultz.com>
66
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
67
+ * @link http://pear.php.net/package/Net_DNS2
68
+ * @see Net_DNS2_RR
69
+ *
70
+ */
71
+ class Net_DNS2_RR_TALINK extends Net_DNS2_RR
72
+ {
73
+ /*
74
+ * the previous domain name
75
+ */
76
+ public $previous;
77
+
78
+ /*
79
+ * the next domain name
80
+ */
81
+ public $next;
82
+
83
+ /**
84
+ * method to return the rdata portion of the packet as a string
85
+ *
86
+ * @return string
87
+ * @access protected
88
+ *
89
+ */
90
+ protected function rrToString()
91
+ {
92
+ return $this->cleanString($this->previous) . '. ' .
93
+ $this->cleanString($this->next) . '.';
94
+ }
95
+
96
+ /**
97
+ * parses the rdata portion from a standard DNS config line
98
+ *
99
+ * @param array $rdata a string split line of values for the rdata
100
+ *
101
+ * @return boolean
102
+ * @access protected
103
+ *
104
+ */
105
+ protected function rrFromString(array $rdata)
106
+ {
107
+ $this->previous = $this->cleanString($rdata[0]);
108
+ $this->next = $this->cleanString($rdata[1]);
109
+
110
+ return true;
111
+ }
112
+
113
+ /**
114
+ * parses the rdata of the Net_DNS2_Packet object
115
+ *
116
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
117
+ *
118
+ * @return boolean
119
+ * @access protected
120
+ *
121
+ */
122
+ protected function rrSet(Net_DNS2_Packet &$packet)
123
+ {
124
+ if ($this->rdlength > 0) {
125
+
126
+ $offset = $packet->offset;
127
+
128
+ $this->previous = Net_DNS2_Packet::label($packet, $offset);
129
+ $this->next = Net_DNS2_Packet::label($packet, $offset);
130
+
131
+ return true;
132
+ }
133
+
134
+ return false;
135
+ }
136
+
137
+ /**
138
+ * returns the rdata portion of the DNS packet
139
+ *
140
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
141
+ * compressed names
142
+ *
143
+ * @return mixed either returns a binary packed
144
+ * string or null on failure
145
+ * @access protected
146
+ *
147
+ */
148
+ protected function rrGet(Net_DNS2_Packet &$packet)
149
+ {
150
+ if ( (strlen($this->previous) > 0) || (strlen($this->next) > 0) ) {
151
+
152
+ $data = chr(strlen($this->previous)) . $this->previous .
153
+ chr(strlen($this->next)) . $this->next;
154
+
155
+ $packet->offset += strlen($data);
156
+
157
+ return $data;
158
+ }
159
+
160
+ return null;
161
+ }
162
+ }
163
+
164
+ /*
165
+ * Local variables:
166
+ * tab-width: 4
167
+ * c-basic-offset: 4
168
+ * c-hanging-comment-ender-p: nil
169
+ * End:
170
+ */
171
+ ?>
includes/Net/DNS2/RR/TKEY.php ADDED
@@ -0,0 +1,307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * TKEY Resource Record - RFC 2930 section 2
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * / ALGORITHM /
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * | INCEPTION |
59
+ * | |
60
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
61
+ * | EXPIRATION |
62
+ * | |
63
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
64
+ * | MODE |
65
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
66
+ * | ERROR |
67
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
68
+ * | KEY SIZE |
69
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
70
+ * / KEY DATA /
71
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
72
+ * | OTHER SIZE |
73
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
74
+ * / OTHER DATA /
75
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
76
+ *
77
+ * @category Networking
78
+ * @package Net_DNS2
79
+ * @author Mike Pultz <mike@mikepultz.com>
80
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
81
+ * @link http://pear.php.net/package/Net_DNS2
82
+ * @see Net_DNS2_RR
83
+ *
84
+ */
85
+ class Net_DNS2_RR_TKEY extends Net_DNS2_RR
86
+ {
87
+ public $algorithm;
88
+ public $inception;
89
+ public $expiration;
90
+ public $mode;
91
+ public $error;
92
+ public $key_size;
93
+ public $key_data;
94
+ public $other_size;
95
+ public $other_data;
96
+
97
+ /*
98
+ * TSIG Modes
99
+ */
100
+ const TSIG_MODE_RES = 0;
101
+ const TSIG_MODE_SERV_ASSIGN = 1;
102
+ const TSIG_MODE_DH = 2;
103
+ const TSIG_MODE_GSS_API = 3;
104
+ const TSIG_MODE_RESV_ASSIGN = 4;
105
+ const TSIG_MODE_KEY_DELE = 5;
106
+
107
+ /*
108
+ * map the mod id's to names so we can validate
109
+ */
110
+ public $tsgi_mode_id_to_name = array(
111
+
112
+ self::TSIG_MODE_RES => 'Reserved',
113
+ self::TSIG_MODE_SERV_ASSIGN => 'Server Assignment',
114
+ self::TSIG_MODE_DH => 'Diffie-Hellman',
115
+ self::TSIG_MODE_GSS_API => 'GSS-API',
116
+ self::TSIG_MODE_RESV_ASSIGN => 'Resolver Assignment',
117
+ self::TSIG_MODE_KEY_DELE => 'Key Deletion'
118
+ );
119
+
120
+ /**
121
+ * method to return the rdata portion of the packet as a string
122
+ *
123
+ * @return string
124
+ * @access protected
125
+ *
126
+ */
127
+ protected function rrToString()
128
+ {
129
+ $out = $this->cleanString($this->algorithm) . '. ' . $this->mode;
130
+ if ($this->key_size > 0) {
131
+
132
+ $out .= ' ' . trim($this->key_data, '.') . '.';
133
+ } else {
134
+
135
+ $out .= ' .';
136
+ }
137
+
138
+ return $out;
139
+ }
140
+
141
+ /**
142
+ * parses the rdata portion from a standard DNS config line
143
+ *
144
+ * @param array $rdata a string split line of values for the rdata
145
+ *
146
+ * @return boolean
147
+ * @access protected
148
+ *
149
+ */
150
+ protected function rrFromString(array $rdata)
151
+ {
152
+ //
153
+ // data passed in is assumed: <algorithm> <mode> <key>
154
+ //
155
+ $this->algorithm = $this->cleanString(array_shift($rdata));
156
+ $this->mode = array_shift($rdata);
157
+ $this->key_data = trim(array_shift($rdata), '.');
158
+
159
+ //
160
+ // the rest of the data is set manually
161
+ //
162
+ $this->inception = time();
163
+ $this->expiration = time() + 86400; // 1 day
164
+ $this->error = 0;
165
+ $this->key_size = strlen($this->key_data);
166
+ $this->other_size = 0;
167
+ $this->other_data = '';
168
+
169
+ return true;
170
+ }
171
+
172
+ /**
173
+ * parses the rdata of the Net_DNS2_Packet object
174
+ *
175
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
176
+ *
177
+ * @return boolean
178
+ * @access protected
179
+ *
180
+ */
181
+ protected function rrSet(Net_DNS2_Packet &$packet)
182
+ {
183
+ if ($this->rdlength > 0) {
184
+
185
+ //
186
+ // expand the algorithm
187
+ //
188
+ $offset = $packet->offset;
189
+ $this->algorithm = Net_DNS2_Packet::expand($packet, $offset);
190
+
191
+ //
192
+ // unpack inception, expiration, mode, error and key size
193
+ //
194
+ $x = unpack(
195
+ '@' . $offset . '/Ninception/Nexpiration/nmode/nerror/nkey_size',
196
+ $packet->rdata
197
+ );
198
+
199
+ $this->inception = Net_DNS2::expandUint32($x['inception']);
200
+ $this->expiration = Net_DNS2::expandUint32($x['expiration']);
201
+ $this->mode = $x['mode'];
202
+ $this->error = $x['error'];
203
+ $this->key_size = $x['key_size'];
204
+
205
+ $offset += 14;
206
+
207
+ //
208
+ // if key_size > 0, then copy out the key
209
+ //
210
+ if ($this->key_size > 0) {
211
+
212
+ $this->key_data = substr($packet->rdata, $offset, $this->key_size);
213
+ $offset += $this->key_size;
214
+ }
215
+
216
+ //
217
+ // unpack the other length
218
+ //
219
+ $x = unpack('@' . $offset . '/nother_size', $packet->rdata);
220
+
221
+ $this->other_size = $x['other_size'];
222
+ $offset += 2;
223
+
224
+ //
225
+ // if other_size > 0, then copy out the data
226
+ //
227
+ if ($this->other_size > 0) {
228
+
229
+ $this->other_data = substr(
230
+ $packet->rdata, $offset, $this->other_size
231
+ );
232
+ }
233
+
234
+ return true;
235
+ }
236
+
237
+ return false;
238
+ }
239
+
240
+ /**
241
+ * returns the rdata portion of the DNS packet
242
+ *
243
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
244
+ * compressed names
245
+ *
246
+ * @return mixed either returns a binary packed
247
+ * string or null on failure
248
+ * @access protected
249
+ *
250
+ */
251
+ protected function rrGet(Net_DNS2_Packet &$packet)
252
+ {
253
+ if (strlen($this->algorithm) > 0) {
254
+
255
+ //
256
+ // make sure the size values are correct
257
+ //
258
+ $this->key_size = strlen($this->key_data);
259
+ $this->other_size = strlen($this->other_data);
260
+
261
+ //
262
+ // add the algorithm without compression
263
+ //
264
+ $data = Net_DNS2_Packet::pack($this->algorithm);
265
+
266
+ //
267
+ // pack in the inception, expiration, mode, error and key size
268
+ //
269
+ $data .= pack(
270
+ 'NNnnn', $this->inception, $this->expiration,
271
+ $this->mode, 0, $this->key_size
272
+ );
273
+
274
+ //
275
+ // if the key_size > 0, then add the key
276
+ //
277
+ if ($this->key_size > 0) {
278
+
279
+ $data .= $this->key_data;
280
+ }
281
+
282
+ //
283
+ // pack in the other size
284
+ //
285
+ $data .= pack('n', $this->other_size);
286
+ if ($this->other_size > 0) {
287
+
288
+ $data .= $this->other_data;
289
+ }
290
+
291
+ $packet->offset += strlen($data);
292
+
293
+ return $data;
294
+ }
295
+
296
+ return null;
297
+ }
298
+ }
299
+
300
+ /*
301
+ * Local variables:
302
+ * tab-width: 4
303
+ * c-basic-offset: 4
304
+ * c-hanging-comment-ender-p: nil
305
+ * End:
306
+ */
307
+ ?>
includes/Net/DNS2/RR/TLSA.php ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2012, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2012 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.2.5
49
+ *
50
+ */
51
+
52
+ /**
53
+ * TLSA Resource Record - RFC 6698
54
+ *
55
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * | Cert. Usage | Selector | Matching Type | /
58
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /
59
+ * / /
60
+ * / Certificate Association Data /
61
+ * / /
62
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
+ *
64
+ * @category Networking
65
+ * @package Net_DNS2
66
+ * @author Mike Pultz <mike@mikepultz.com>
67
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
68
+ * @link http://pear.php.net/package/Net_DNS2
69
+ * @see Net_DNS2_RR
70
+ *
71
+ */
72
+ class Net_DNS2_RR_TLSA extends Net_DNS2_RR
73
+ {
74
+ /*
75
+ * The Certificate Usage Field
76
+ */
77
+ public $cert_usage;
78
+
79
+ /*
80
+ * The Selector Field
81
+ */
82
+ public $selector;
83
+
84
+ /*
85
+ * The Matching Type Field
86
+ */
87
+ public $matching_type;
88
+
89
+ /*
90
+ * The Certificate Association Data Field
91
+ */
92
+ public $certificate;
93
+
94
+ /**
95
+ * method to return the rdata portion of the packet as a string
96
+ *
97
+ * @return string
98
+ * @access protected
99
+ *
100
+ */
101
+ protected function rrToString()
102
+ {
103
+ return $this->cert_usage . ' ' . $this->selector . ' ' .
104
+ $this->matching_type . ' ' . base64_encode($this->certificate);
105
+ }
106
+
107
+ /**
108
+ * parses the rdata portion from a standard DNS config line
109
+ *
110
+ * @param array $rdata a string split line of values for the rdata
111
+ *
112
+ * @return boolean
113
+ * @access protected
114
+ *
115
+ */
116
+ protected function rrFromString(array $rdata)
117
+ {
118
+ $this->cert_usage = array_shift($rdata);
119
+ $this->selector = array_shift($rdata);
120
+ $this->matching_type = array_shift($rdata);
121
+ $this->certificate = base64_decode(implode('', $rdata));
122
+
123
+ return true;
124
+ }
125
+
126
+ /**
127
+ * parses the rdata of the Net_DNS2_Packet object
128
+ *
129
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
130
+ *
131
+ * @return boolean
132
+ * @access protected
133
+ *
134
+ */
135
+ protected function rrSet(Net_DNS2_Packet &$packet)
136
+ {
137
+ if ($this->rdlength > 0) {
138
+
139
+ //
140
+ // unpack the format, keytag and algorithm
141
+ //
142
+ $x = unpack('Cusage/Cselector/Ctype', $this->rdata);
143
+
144
+ $this->cert_usage = $x['usage'];
145
+ $this->selector = $x['selector'];
146
+ $this->matching_type = $x['type'];
147
+
148
+ //
149
+ // copy the certificate
150
+ //
151
+ $this->certificate = substr($this->rdata, 3, $this->rdlength - 3);
152
+
153
+ return true;
154
+ }
155
+
156
+ return false;
157
+ }
158
+
159
+ /**
160
+ * returns the rdata portion of the DNS packet
161
+ *
162
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
163
+ * compressed names
164
+ *
165
+ * @return mixed either returns a binary packed
166
+ * string or null on failure
167
+ * @access protected
168
+ *
169
+ */
170
+ protected function rrGet(Net_DNS2_Packet &$packet)
171
+ {
172
+ if (strlen($this->certificate) > 0) {
173
+
174
+ $data = pack(
175
+ 'CCC', $this->cert_usage, $this->selector, $this->matching_type
176
+ ) . $this->certificate;
177
+
178
+ $packet->offset += strlen($data);
179
+
180
+ return $data;
181
+ }
182
+
183
+ return null;
184
+ }
185
+ }
186
+
187
+ /*
188
+ * Local variables:
189
+ * tab-width: 4
190
+ * c-basic-offset: 4
191
+ * c-hanging-comment-ender-p: nil
192
+ * End:
193
+ */
194
+ ?>
includes/Net/DNS2/RR/TSIG.php ADDED
@@ -0,0 +1,504 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * TSIG Resource Record - RFC 2845
54
+ *
55
+ * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
56
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
+ * / algorithm /
58
+ * / /
59
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60
+ * | time signed |
61
+ * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62
+ * | | fudge |
63
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64
+ * | mac size | /
65
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /
66
+ * / mac /
67
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68
+ * | original id | error |
69
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70
+ * | other length | /
71
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /
72
+ * / other data /
73
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74
+ *
75
+ * @category Networking
76
+ * @package Net_DNS2
77
+ * @author Mike Pultz <mike@mikepultz.com>
78
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
79
+ * @link http://pear.php.net/package/Net_DNS2
80
+ * @see Net_DNS2_RR
81
+ *
82
+ */
83
+ class Net_DNS2_RR_TSIG extends Net_DNS2_RR
84
+ {
85
+ /*
86
+ * TSIG Algorithm Identifiers
87
+ */
88
+ const HMAC_MD5 = 'hmac-md5.sig-alg.reg.int'; // RFC 2845, required
89
+ const GSS_TSIG = 'gss-tsig'; // unsupported, optional
90
+ const HMAC_SHA1 = 'hmac-sha1'; // RFC 4635, required
91
+ const HMAC_SHA224 = 'hmac-sha224'; // RFC 4635, optional
92
+ const HMAC_SHA256 = 'hmac-sha256'; // RFC 4635, required
93
+ const HMAC_SHA384 = 'hmac-sha384'; // RFC 4635, optional
94
+ const HMAC_SHA512 = 'hmac-sha512'; // RFC 4635, optional
95
+
96
+ /*
97
+ * the map of hash values to names
98
+ */
99
+ public static $hash_algorithms = array(
100
+
101
+ self::HMAC_MD5 => 'md5',
102
+ self::HMAC_SHA1 => 'sha1',
103
+ self::HMAC_SHA224 => 'sha224',
104
+ self::HMAC_SHA256 => 'sha256',
105
+ self::HMAC_SHA384 => 'sha384',
106
+ self::HMAC_SHA512 => 'sha512'
107
+ );
108
+
109
+ /*
110
+ * algorithm used; only supports HMAC-MD5
111
+ */
112
+ public $algorithm;
113
+
114
+ /*
115
+ * The time it was signed
116
+ */
117
+ public $time_signed;
118
+
119
+ /*
120
+ * fudge- allowed offset from the time signed
121
+ */
122
+ public $fudge;
123
+
124
+ /*
125
+ * size of the digest
126
+ */
127
+ public $mac_size;
128
+
129
+ /*
130
+ * the digest data
131
+ */
132
+ public $mac;
133
+
134
+ /*
135
+ * the original id of the request
136
+ */
137
+ public $original_id;
138
+
139
+ /*
140
+ * additional error code
141
+ */
142
+ public $error;
143
+
144
+ /*
145
+ * length of the "other" data, should only ever be 0 when there is
146
+ * no error, or 6 when there is the error RCODE_BADTIME
147
+ */
148
+ public $other_length;
149
+
150
+ /*
151
+ * the other data; should only ever be a timestamp when there is the
152
+ * error RCODE_BADTIME
153
+ */
154
+ public $other_data;
155
+
156
+ /*
157
+ * the key to use for signing - passed in, not included in the rdata
158
+ */
159
+ public $key;
160
+
161
+ /**
162
+ * method to return the rdata portion of the packet as a string
163
+ *
164
+ * @return string
165
+ * @access protected
166
+ *
167
+ */
168
+ protected function rrToString()
169
+ {
170
+ $out = $this->cleanString($this->algorithm) . '. ' .
171
+ $this->time_signed . ' ' .
172
+ $this->fudge . ' ' . $this->mac_size . ' ' .
173
+ base64_encode($this->mac) . ' ' . $this->original_id . ' ' .
174
+ $this->error . ' '. $this->other_length;
175
+
176
+ if ($this->other_length > 0) {
177
+
178
+ $out .= ' ' . $this->other_data;
179
+ }
180
+
181
+ return $out;
182
+ }
183
+
184
+ /**
185
+ * parses the rdata portion from a standard DNS config line
186
+ *
187
+ * @param array $rdata a string split line of values for the rdata
188
+ *
189
+ * @return boolean
190
+ * @access protected
191
+ *
192
+ */
193
+ protected function rrFromString(array $rdata)
194
+ {
195
+ //
196
+ // the only value passed in is the key-
197
+ //
198
+ // this assumes it's passed in base64 encoded.
199
+ //
200
+ $this->key = preg_replace('/\s+/', '', array_shift($rdata));
201
+
202
+ //
203
+ // the rest of the data is set to default
204
+ //
205
+ $this->algorithm = self::HMAC_MD5;
206
+ $this->time_signed = time();
207
+ $this->fudge = 300;
208
+ $this->mac_size = 0;
209
+ $this->mac = '';
210
+ $this->original_id = 0;
211
+ $this->error = 0;
212
+ $this->other_length = 0;
213
+ $this->other_data = '';
214
+
215
+ //
216
+ // per RFC 2845 section 2.3
217
+ //
218
+ $this->class = 'ANY';
219
+ $this->ttl = 0;
220
+
221
+ return true;
222
+ }
223
+
224
+ /**
225
+ * parses the rdata of the Net_DNS2_Packet object
226
+ *
227
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
228
+ *
229
+ * @return boolean
230
+ * @access protected
231
+ *
232
+ */
233
+ protected function rrSet(Net_DNS2_Packet &$packet)
234
+ {
235
+ if ($this->rdlength > 0) {
236
+
237
+ //
238
+ // expand the algorithm
239
+ //
240
+ $newoffset = $packet->offset;
241
+ $this->algorithm = Net_DNS2_Packet::expand($packet, $newoffset);
242
+ $offset = $newoffset - $packet->offset;
243
+
244
+ //
245
+ // unpack time, fudge and mac_size
246
+ //
247
+ $x = unpack(
248
+ '@' . $offset . '/ntime_high/Ntime_low/nfudge/nmac_size',
249
+ $this->rdata
250
+ );
251
+
252
+ $this->time_signed = Net_DNS2::expandUint32($x['time_low']);
253
+ $this->fudge = $x['fudge'];
254
+ $this->mac_size = $x['mac_size'];
255
+
256
+ $offset += 10;
257
+
258
+ //
259
+ // copy out the mac
260
+ //
261
+ if ($this->mac_size > 0) {
262
+
263
+ $this->mac = substr($this->rdata, $offset, $this->mac_size);
264
+ $offset += $this->mac_size;
265
+ }
266
+
267
+ //
268
+ // unpack the original id, error, and other_length values
269
+ //
270
+ $x = unpack(
271
+ '@' . $offset . '/noriginal_id/nerror/nother_length',
272
+ $this->rdata
273
+ );
274
+
275
+ $this->original_id = $x['original_id'];
276
+ $this->error = $x['error'];
277
+ $this->other_length = $x['other_length'];
278
+
279
+ //
280
+ // the only time there is actually any "other data", is when there's
281
+ // a BADTIME error code.
282
+ //
283
+ // The other length should be 6, and the other data field includes the
284
+ // servers current time - per RFC 2845 section 4.5.2
285
+ //
286
+ if ($this->error == Net_DNS2_Lookups::RCODE_BADTIME) {
287
+
288
+ if ($this->other_length != 6) {
289
+
290
+ return false;
291
+ }
292
+
293
+ //
294
+ // other data is a 48bit timestamp
295
+ //
296
+ $x = unpack(
297
+ 'nhigh/nlow',
298
+ substr($this->rdata, $offset + 6, $this->other_length)
299
+ );
300
+ $this->other_data = $x['low'];
301
+ }
302
+
303
+ return true;
304
+ }
305
+
306
+ return false;
307
+ }
308
+
309
+ /**
310
+ * returns the rdata portion of the DNS packet
311
+ *
312
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
313
+ * compressed names
314
+ *
315
+ * @return mixed either returns a binary packed
316
+ * string or null on failure
317
+ * @access protected
318
+ *
319
+ */
320
+ protected function rrGet(Net_DNS2_Packet &$packet)
321
+ {
322
+ if (strlen($this->key) > 0) {
323
+
324
+ //
325
+ // create a new packet for the signature-
326
+ //
327
+ $new_packet = new Net_DNS2_Packet_Request('example.com', 'SOA', 'IN');
328
+
329
+ //
330
+ // copy the packet data over
331
+ //
332
+ $new_packet->copy($packet);
333
+
334
+ //
335
+ // remove the TSIG object from the additional list
336
+ //
337
+ array_pop($new_packet->additional);
338
+ $new_packet->header->arcount = count($new_packet->additional);
339
+
340
+ //
341
+ // copy out the data
342
+ //
343
+ $sig_data = $new_packet->get();
344
+
345
+ //
346
+ // add the name without compressing
347
+ //
348
+ $sig_data .= Net_DNS2_Packet::pack($this->name);
349
+
350
+ //
351
+ // add the class and TTL
352
+ //
353
+ $sig_data .= pack(
354
+ 'nN', Net_DNS2_Lookups::$classes_by_name[$this->class], $this->ttl
355
+ );
356
+
357
+ //
358
+ // add the algorithm name without compression
359
+ //
360
+ $sig_data .= Net_DNS2_Packet::pack(strtolower($this->algorithm));
361
+
362
+ //
363
+ // add the rest of the values
364
+ //
365
+ $sig_data .= pack(
366
+ 'nNnnn', 0, $this->time_signed, $this->fudge,
367
+ $this->error, $this->other_length
368
+ );
369
+ if ($this->other_length > 0) {
370
+
371
+ $sig_data .= pack('nN', 0, $this->other_data);
372
+ }
373
+
374
+ //
375
+ // sign the data
376
+ //
377
+ $this->mac = $this->_signHMAC(
378
+ $sig_data, base64_decode($this->key), $this->algorithm
379
+ );
380
+ $this->mac_size = strlen($this->mac);
381
+
382
+ //
383
+ // compress the algorithm
384
+ //
385
+ $data = Net_DNS2_Packet::pack(strtolower($this->algorithm));
386
+
387
+ //
388
+ // pack the time, fudge and mac size
389
+ //
390
+ $data .= pack(
391
+ 'nNnn', 0, $this->time_signed, $this->fudge, $this->mac_size
392
+ );
393
+ $data .= $this->mac;
394
+
395
+ //
396
+ // check the error and other_length
397
+ //
398
+ if ($this->error == Net_DNS2_Lookups::RCODE_BADTIME) {
399
+
400
+ $this->other_length = strlen($this->other_data);
401
+ if ($this->other_length != 6) {
402
+
403
+ return null;
404
+ }
405
+ } else {
406
+
407
+ $this->other_length = 0;
408
+ $this->other_data = '';
409
+ }
410
+
411
+ //
412
+ // pack the id, error and other_length
413
+ //
414
+ $data .= pack(
415
+ 'nnn', $packet->header->id, $this->error, $this->other_length
416
+ );
417
+ if ($this->other_length > 0) {
418
+
419
+ $data .= pack('nN', 0, $this->other_data);
420
+ }
421
+
422
+ $packet->offset += strlen($data);
423
+
424
+ return $data;
425
+ }
426
+
427
+ return null;
428
+ }
429
+
430
+ /**
431
+ * signs the given data with the given key, and returns the result
432
+ *
433
+ * @param string $data the data to sign
434
+ * @param string $key key to use for signing
435
+ * @param string $algorithm the algorithm to use; defaults to MD5
436
+ *
437
+ * @return string the signed digest
438
+ * @throws Net_DNS2_Exception
439
+ * @access private
440
+ *
441
+ */
442
+ private function _signHMAC($data, $key = null, $algorithm = self::HMAC_MD5)
443
+ {
444
+ //
445
+ // use the hash extension; this is included by default in >= 5.1.2 which
446
+ // is our dependent version anyway- so it's easy to switch to it.
447
+ //
448
+ if (extension_loaded('hash')) {
449
+
450
+ if (!isset(self::$hash_algorithms[$algorithm])) {
451
+
452
+ throw new Net_DNS2_Exception(
453
+ 'invalid or unsupported algorithm',
454
+ Net_DNS2_Lookups::E_PARSE_ERROR
455
+ );
456
+ }
457
+
458
+ return hash_hmac(self::$hash_algorithms[$algorithm], $data, $key, true);
459
+ }
460
+
461
+ //
462
+ // if the hash extension isn't loaded, and they selected something other
463
+ // than MD5, throw an exception
464
+ //
465
+ if ($algorithm != self::HMAC_MD5) {
466
+
467
+ throw new Net_DNS2_Exception(
468
+ 'only HMAC-MD5 supported. please install the php-extension ' .
469
+ '"hash" in order to use the sha-family',
470
+ Net_DNS2_Lookups::E_PARSE_ERROR
471
+ );
472
+ }
473
+
474
+ //
475
+ // otherwise, do it ourselves
476
+ //
477
+ if (is_null($key)) {
478
+
479
+ return pack('H*', md5($data));
480
+ }
481
+
482
+ $key = str_pad($key, 64, chr(0x00));
483
+ if (strlen($key) > 64) {
484
+
485
+ $key = pack('H*', md5($key));
486
+ }
487
+
488
+ $k_ipad = $key ^ str_repeat(chr(0x36), 64);
489
+ $k_opad = $key ^ str_repeat(chr(0x5c), 64);
490
+
491
+ return $this->_signHMAC(
492
+ $k_opad . pack('H*', md5($k_ipad . $data)), null, $algorithm
493
+ );
494
+ }
495
+ }
496
+
497
+ /*
498
+ * Local variables:
499
+ * tab-width: 4
500
+ * c-basic-offset: 4
501
+ * c-hanging-comment-ender-p: nil
502
+ * End:
503
+ */
504
+ ?>
includes/Net/DNS2/RR/TXT.php ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * TXT Resource Record - RFC1035 section 3.3.14
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * / TXT-DATA /
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ *
59
+ * @category Networking
60
+ * @package Net_DNS2
61
+ * @author Mike Pultz <mike@mikepultz.com>
62
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
63
+ * @link http://pear.php.net/package/Net_DNS2
64
+ * @see Net_DNS2_RR
65
+ *
66
+ */
67
+ class Net_DNS2_RR_TXT extends Net_DNS2_RR
68
+ {
69
+ /*
70
+ * an array of the text strings
71
+ */
72
+ public $text = array();
73
+
74
+ /**
75
+ * method to return the rdata portion of the packet as a string
76
+ *
77
+ * @return string
78
+ * @access protected
79
+ *
80
+ */
81
+ protected function rrToString()
82
+ {
83
+ if (count($this->text) == 0) {
84
+ return '""';
85
+ }
86
+
87
+ $data = '';
88
+
89
+ foreach ($this->text as $t) {
90
+
91
+ $data .= $this->formatString($t) . ' ';
92
+ }
93
+
94
+ return trim($data);
95
+ }
96
+
97
+ /**
98
+ * parses the rdata portion from a standard DNS config line
99
+ *
100
+ * @param array $rdata a string split line of values for the rdata
101
+ *
102
+ * @return boolean
103
+ * @access protected
104
+ *
105
+ */
106
+ protected function rrFromString(array $rdata)
107
+ {
108
+ $data = $this->buildString($rdata);
109
+ if (count($data) > 0) {
110
+
111
+ $this->text = $data;
112
+ }
113
+
114
+ return true;
115
+ }
116
+
117
+ /**
118
+ * parses the rdata of the Net_DNS2_Packet object
119
+ *
120
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
121
+ *
122
+ * @return boolean
123
+ * @access protected
124
+ *
125
+ */
126
+ protected function rrSet(Net_DNS2_Packet &$packet)
127
+ {
128
+ if ($this->rdlength > 0) {
129
+
130
+ $length = $packet->offset + $this->rdlength;
131
+ $offset = $packet->offset;
132
+
133
+ while ($length > $offset) {
134
+
135
+ $this->text[] = Net_DNS2_Packet::label($packet, $offset);
136
+ }
137
+
138
+ return true;
139
+ }
140
+
141
+ return false;
142
+ }
143
+
144
+ /**
145
+ * returns the rdata portion of the DNS packet
146
+ *
147
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
148
+ * compressed names
149
+ *
150
+ * @return mixed either returns a binary packed
151
+ * string or null on failure
152
+ * @access protected
153
+ *
154
+ */
155
+ protected function rrGet(Net_DNS2_Packet &$packet)
156
+ {
157
+ $data = null;
158
+
159
+ foreach ($this->text as $t) {
160
+
161
+ $data .= chr(strlen($t)) . $t;
162
+ }
163
+
164
+ $packet->offset += strlen($data);
165
+
166
+ return $data;
167
+ }
168
+ }
169
+
170
+ /*
171
+ * Local variables:
172
+ * tab-width: 4
173
+ * c-basic-offset: 4
174
+ * c-hanging-comment-ender-p: nil
175
+ * End:
176
+ */
177
+ ?>
includes/Net/DNS2/RR/URI.php ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2011, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2011 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.2.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * URI Resource Record - http://tools.ietf.org/html/draft-faltstrom-uri-06
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | PRIORITY |
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * | WEIGHT |
59
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
60
+ * / TARGET /
61
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
62
+ *
63
+ * @category Networking
64
+ * @package Net_DNS2
65
+ * @author Mike Pultz <mike@mikepultz.com>
66
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
67
+ * @link http://pear.php.net/package/Net_DNS2
68
+ * @see Net_DNS2_RR
69
+ *
70
+ */
71
+ class Net_DNS2_RR_URI extends Net_DNS2_RR
72
+ {
73
+ /*
74
+ * The priority of this target host.
75
+ */
76
+ public $priority;
77
+
78
+ /*
79
+ * a relative weight for entries with the same priority
80
+ */
81
+ public $weight;
82
+
83
+ /*
84
+ * The domain name of the target host
85
+ */
86
+ public $target;
87
+
88
+ /**
89
+ * method to return the rdata portion of the packet as a string
90
+ *
91
+ * @return string
92
+ * @access protected
93
+ *
94
+ */
95
+ protected function rrToString()
96
+ {
97
+ //
98
+ // presentation format has double quotes (") around the target.
99
+ //
100
+ return $this->priority . ' ' . $this->weight . ' "' .
101
+ $this->cleanString($this->target) . '"';
102
+ }
103
+
104
+ /**
105
+ * parses the rdata portion from a standard DNS config line
106
+ *
107
+ * @param array $rdata a string split line of values for the rdata
108
+ *
109
+ * @return boolean
110
+ * @access protected
111
+ *
112
+ */
113
+ protected function rrFromString(array $rdata)
114
+ {
115
+ $this->priority = $rdata[0];
116
+ $this->weight = $rdata[1];
117
+
118
+ //
119
+ // make sure to trim the lead/trailing double quote if it's there.
120
+ //
121
+ $this->target = trim($this->cleanString($rdata[2]), '"');
122
+
123
+ return true;
124
+ }
125
+
126
+ /**
127
+ * parses the rdata of the Net_DNS2_Packet object
128
+ *
129
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
130
+ *
131
+ * @return boolean
132
+ * @access protected
133
+ *
134
+ */
135
+ protected function rrSet(Net_DNS2_Packet &$packet)
136
+ {
137
+ if ($this->rdlength > 0) {
138
+
139
+ //
140
+ // unpack the priority and weight
141
+ //
142
+ $x = unpack('npriority/nweight', $this->rdata);
143
+
144
+ $this->priority = $x['priority'];
145
+ $this->weight = $x['weight'];
146
+
147
+ $offset = $packet->offset + 4;
148
+ $this->target = Net_DNS2_Packet::expand($packet, $offset);
149
+
150
+ return true;
151
+ }
152
+
153
+ return false;
154
+ }
155
+
156
+ /**
157
+ * returns the rdata portion of the DNS packet
158
+ *
159
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
160
+ * compressed names
161
+ *
162
+ * @return mixed either returns a binary packed
163
+ * string or null on failure
164
+ * @access protected
165
+ *
166
+ */
167
+ protected function rrGet(Net_DNS2_Packet &$packet)
168
+ {
169
+ if (strlen($this->target) > 0) {
170
+
171
+ $data = pack('nn', $this->priority, $this->weight);
172
+ $packet->offset += 4;
173
+
174
+ $data .= $packet->compress(trim($this->target, '"'), $packet->offset);
175
+
176
+ return $data;
177
+ }
178
+
179
+ return null;
180
+ }
181
+ }
182
+
183
+ ?>
includes/Net/DNS2/RR/WKS.php ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 1.0.1
49
+ *
50
+ */
51
+
52
+ /**
53
+ * WKS Resource Record - RFC1035 section 3.4.2
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * | ADDRESS |
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ * | PROTOCOL | |
59
+ * +--+--+--+--+--+--+--+--+ |
60
+ * | |
61
+ * / <BIT MAP> /
62
+ * / /
63
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
64
+ *
65
+ * @category Networking
66
+ * @package Net_DNS2
67
+ * @author Mike Pultz <mike@mikepultz.com>
68
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
69
+ * @link http://pear.php.net/package/Net_DNS2
70
+ * @see Net_DNS2_RR
71
+ *
72
+ */
73
+ class Net_DNS2_RR_WKS extends Net_DNS2_RR
74
+ {
75
+ /*
76
+ * The IP address of the service
77
+ */
78
+ public $address;
79
+
80
+ /*
81
+ * The protocol of the service
82
+ */
83
+ public $protocol;
84
+
85
+ /*
86
+ * bitmap
87
+ */
88
+ public $bitmap = array();
89
+
90
+ /**
91
+ * method to return the rdata portion of the packet as a string
92
+ *
93
+ * @return string
94
+ * @access protected
95
+ *
96
+ */
97
+ protected function rrToString()
98
+ {
99
+ $data = $this->address . ' ' . $this->protocol;
100
+
101
+ foreach ($this->bitmap as $port) {
102
+ $data .= ' ' . $port;
103
+ }
104
+
105
+ return $data;
106
+ }
107
+
108
+ /**
109
+ * parses the rdata portion from a standard DNS config line
110
+ *
111
+ * @param array $rdata a string split line of values for the rdata
112
+ *
113
+ * @return boolean
114
+ * @access protected
115
+ *
116
+ */
117
+ protected function rrFromString(array $rdata)
118
+ {
119
+ $this->address = strtolower(trim(array_shift($rdata), '.'));
120
+ $this->protocol = array_shift($rdata);
121
+ $this->bitmap = $rdata;
122
+
123
+ return true;
124
+ }
125
+
126
+ /**
127
+ * parses the rdata of the Net_DNS2_Packet object
128
+ *
129
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
130
+ *
131
+ * @return boolean
132
+ * @access protected
133
+ *
134
+ */
135
+ protected function rrSet(Net_DNS2_Packet &$packet)
136
+ {
137
+ if ($this->rdlength > 0) {
138
+
139
+ //
140
+ // get the address and protocol value
141
+ //
142
+ $x = unpack('Naddress/Cprotocol', $this->rdata);
143
+
144
+ $this->address = long2ip($x['address']);
145
+ $this->protocol = $x['protocol'];
146
+
147
+ //
148
+ // unpack the port list bitmap
149
+ //
150
+ $port = 0;
151
+ foreach (unpack('@5/C*', $this->rdata) as $set) {
152
+
153
+ $s = sprintf('%08b', $set);
154
+
155
+ for ($i=0; $i<8; $i++, $port++) {
156
+ if ($s[$i] == '1') {
157
+ $this->bitmap[] = $port;
158
+ }
159
+ }
160
+ }
161
+
162
+ return true;
163
+ }
164
+
165
+ return false;
166
+ }
167
+
168
+ /**
169
+ * returns the rdata portion of the DNS packet
170
+ *
171
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
172
+ * compressed names
173
+ *
174
+ * @return mixed either returns a binary packed
175
+ * string or null on failure
176
+ * @access protected
177
+ *
178
+ */
179
+ protected function rrGet(Net_DNS2_Packet &$packet)
180
+ {
181
+ if (strlen($this->address) > 0) {
182
+
183
+ $data = pack('NC', ip2long($this->address), $this->protocol);
184
+
185
+ $ports = array();
186
+
187
+ $n = 0;
188
+ foreach ($this->bitmap as $port) {
189
+ $ports[$port] = 1;
190
+
191
+ if ($port > $n) {
192
+ $n = $port;
193
+ }
194
+ }
195
+ for ($i=0; $i<ceil($n/8)*8; $i++) {
196
+ if (!isset($ports[$i])) {
197
+ $ports[$i] = 0;
198
+ }
199
+ }
200
+
201
+ ksort($ports);
202
+
203
+ $string = '';
204
+ $n = 0;
205
+
206
+ foreach ($ports as $s) {
207
+
208
+ $string .= $s;
209
+ $n++;
210
+
211
+ if ($n == 8) {
212
+
213
+ $data .= chr(bindec($string));
214
+ $string = '';
215
+ $n = 0;
216
+ }
217
+ }
218
+
219
+ $packet->offset += strlen($data);
220
+
221
+ return $data;
222
+ }
223
+
224
+ return null;
225
+ }
226
+ }
227
+
228
+ /*
229
+ * Local variables:
230
+ * tab-width: 4
231
+ * c-basic-offset: 4
232
+ * c-hanging-comment-ender-p: nil
233
+ * End:
234
+ */
235
+ ?>
includes/Net/DNS2/RR/X25.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * X25 Resource Record - RFC1183 section 3.1
54
+ *
55
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
56
+ * / PSDN-address /
57
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
58
+ *
59
+ * @category Networking
60
+ * @package Net_DNS2
61
+ * @author Mike Pultz <mike@mikepultz.com>
62
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
63
+ * @link http://pear.php.net/package/Net_DNS2
64
+ * @see Net_DNS2_RR
65
+ *
66
+ */
67
+ class Net_DNS2_RR_X25 extends Net_DNS2_RR
68
+ {
69
+ /*
70
+ * The PSDN address
71
+ */
72
+ public $psdnaddress;
73
+
74
+ /**
75
+ * method to return the rdata portion of the packet as a string
76
+ *
77
+ * @return string
78
+ * @access protected
79
+ *
80
+ */
81
+ protected function rrToString()
82
+ {
83
+ return $this->formatString($this->psdnaddress);
84
+ }
85
+
86
+ /**
87
+ * parses the rdata portion from a standard DNS config line
88
+ *
89
+ * @param array $rdata a string split line of values for the rdata
90
+ *
91
+ * @return boolean
92
+ * @access protected
93
+ *
94
+ */
95
+ protected function rrFromString(array $rdata)
96
+ {
97
+ $data = $this->buildString($rdata);
98
+ if (count($data) == 1) {
99
+
100
+ $this->psdnaddress = $data[0];
101
+ return true;
102
+ }
103
+
104
+ return false;
105
+ }
106
+
107
+ /**
108
+ * parses the rdata of the Net_DNS2_Packet object
109
+ *
110
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
111
+ *
112
+ * @return boolean
113
+ * @access protected
114
+ *
115
+ */
116
+ protected function rrSet(Net_DNS2_Packet &$packet)
117
+ {
118
+ if ($this->rdlength > 0) {
119
+
120
+ $this->psdnaddress = Net_DNS2_Packet::label($packet, $packet->offset);
121
+ return true;
122
+ }
123
+
124
+ return false;
125
+ }
126
+
127
+ /**
128
+ * returns the rdata portion of the DNS packet
129
+ *
130
+ * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
131
+ * compressed names
132
+ *
133
+ * @return mixed either returns a binary packed
134
+ * string or null on failure
135
+ * @access protected
136
+ *
137
+ */
138
+ protected function rrGet(Net_DNS2_Packet &$packet)
139
+ {
140
+ if (strlen($this->psdnaddress) > 0) {
141
+
142
+ $data = chr(strlen($this->psdnaddress)) . $this->psdnaddress;
143
+
144
+ $packet->offset += strlen($data);
145
+
146
+ return $data;
147
+ }
148
+
149
+ return null;
150
+ }
151
+ }
152
+
153
+ /*
154
+ * Local variables:
155
+ * tab-width: 4
156
+ * c-basic-offset: 4
157
+ * c-hanging-comment-ender-p: nil
158
+ * End:
159
+ */
160
+ ?>
includes/Net/DNS2/Resolver.php ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /**
53
+ * This is the main resolver class, providing DNS query functions.
54
+ *
55
+ * @category Networking
56
+ * @package Net_DNS2
57
+ * @author Mike Pultz <mike@mikepultz.com>
58
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
59
+ * @link http://pear.php.net/package/Net_DNS2
60
+ * @see Net_DNS2
61
+ *
62
+ */
63
+ class Net_DNS2_Resolver extends Net_DNS2
64
+ {
65
+ /**
66
+ * Constructor - creates a new Net_DNS2_Resolver object
67
+ *
68
+ * @param mixed $options either an array with options or null
69
+ *
70
+ * @access public
71
+ *
72
+ */
73
+ public function __construct(array $options = null)
74
+ {
75
+ parent::__construct($options);
76
+ }
77
+
78
+ /**
79
+ * does a basic DNS lookup query
80
+ *
81
+ * @param string $name the DNS name to loookup
82
+ * @param string $type the name of the RR type to lookup
83
+ * @param string $class the name of the RR class to lookup
84
+ *
85
+ * @return Net_DNS2_RR object
86
+ * @throws Net_DNS2_Exception
87
+ * @access public
88
+ *
89
+ */
90
+ public function query($name, $type = 'A', $class = 'IN')
91
+ {
92
+ //
93
+ // make sure we have some name servers set
94
+ //
95
+ $this->checkServers(Net_DNS2::RESOLV_CONF);
96
+
97
+ //
98
+ // we dont' support incremental zone tranfers; so if it's requested, a full
99
+ // zone transfer can be returned
100
+ //
101
+ if ($type == 'IXFR') {
102
+
103
+ $type = 'AXFR';
104
+ }
105
+
106
+ //
107
+ // if the name *looks* too short, then append the domain from the config
108
+ //
109
+ if ( (strpos($name, '.') === false) && ($type != 'PTR') ) {
110
+
111
+ $name .= '.' . strtolower($this->domain);
112
+ }
113
+
114
+ //
115
+ // create a new packet based on the input
116
+ //
117
+ $packet = new Net_DNS2_Packet_Request($name, $type, $class);
118
+
119
+ //
120
+ // check for an authentication method; either TSIG or SIG
121
+ //
122
+ if ( ($this->auth_signature instanceof Net_DNS2_RR_TSIG)
123
+ || ($this->auth_signature instanceof Net_DNS2_RR_SIG)
124
+ ) {
125
+ $packet->additional[] = $this->auth_signature;
126
+ $packet->header->arcount = count($packet->additional);
127
+ }
128
+
129
+ //
130
+ // check for the DNSSEC flag, and if it's true, then add an OPT
131
+ // RR to the additional section, and set the DO flag to 1.
132
+ //
133
+ if ($this->dnssec == true) {
134
+
135
+ //
136
+ // create a new OPT RR
137
+ //
138
+ $opt = new Net_DNS2_RR_OPT();
139
+
140
+ //
141
+ // set the DO flag, and the other values
142
+ //
143
+ $opt->do = 1;
144
+ $opt->class = $this->dnssec_payload_size;
145
+
146
+ //
147
+ // add the RR to the additional section.
148
+ //
149
+ $packet->additional[] = $opt;
150
+ $packet->header->arcount = count($packet->additional);
151
+ }
152
+
153
+ //
154
+ // set the DNSSEC AD or CD bits
155
+ //
156
+ if ($this->dnssec_ad_flag == true) {
157
+
158
+ $packet->header->ad = 1;
159
+ }
160
+ if ($this->dnssec_cd_flag == true) {
161
+
162
+ $packet->header->cd = 1;
163
+ }
164
+
165
+ //
166
+ // if caching is turned on, then check then hash the question, and
167
+ // do a cache lookup.
168
+ //
169
+ // don't use the cache for zone transfers
170
+ //
171
+ $packet_hash = '';
172
+
173
+ if ( ($this->use_cache == true) && ($this->cacheable($type) == true) ) {
174
+
175
+ //
176
+ // open the cache
177
+ //
178
+ $this->cache->open(
179
+ $this->cache_file, $this->cache_size, $this->cache_serializer
180
+ );
181
+
182
+ //
183
+ // build the key and check for it in the cache.
184
+ //
185
+ $packet_hash = md5(
186
+ $packet->question[0]->qname . '|' . $packet->question[0]->qtype
187
+ );
188
+
189
+ if ($this->cache->has($packet_hash)) {
190
+
191
+ return $this->cache->get($packet_hash);
192
+ }
193
+ }
194
+
195
+ //
196
+ // set the RD (recursion desired) bit to 1 / 0 depending on the config
197
+ // setting.
198
+ //
199
+ if ($this->recurse == false) {
200
+ $packet->header->rd = 0;
201
+ } else {
202
+ $packet->header->rd = 1;
203
+ }
204
+
205
+ //
206
+ // send the packet and get back the response
207
+ //
208
+ // *always* use TCP for zone transfers- does this cause any problems?
209
+ //
210
+ $response = $this->sendPacket(
211
+ $packet, ($type == 'AXFR') ? true : $this->use_tcp
212
+ );
213
+
214
+ //
215
+ // if strict mode is enabled, then make sure that the name that was
216
+ // looked up is *actually* in the response object.
217
+ //
218
+ // only do this is strict_query_mode is turned on, AND we've received
219
+ // some answers; no point doing any else if there were no answers.
220
+ //
221
+ if ( ($this->strict_query_mode == true)
222
+ && ($response->header->ancount > 0)
223
+ ) {
224
+
225
+ $found = false;
226
+
227
+ //
228
+ // look for the requested name/type/class
229
+ //
230
+ foreach ($response->answer as $index => $object) {
231
+
232
+ if ( (strcasecmp($object->name, $name) == 0)
233
+ && ($object->type == $type)
234
+ && ($object->class == $class)
235
+ ) {
236
+ $found = true;
237
+ break;
238
+ }
239
+ }
240
+
241
+ //
242
+ // if it's not found, then unset the answer section; it's not correct to
243
+ // throw an exception here; if the hostname didn't exist, then
244
+ // sendPacket() would have already thrown an NXDOMAIN error- so the host
245
+ // *exists*, but just not the request type/class.
246
+ //
247
+ // the correct response in this case, is an empty answer section; the
248
+ // authority section may still have usual information, like a SOA record.
249
+ //
250
+ if ($found == false) {
251
+
252
+ $response->answer = array();
253
+ $response->header->ancount = 0;
254
+ }
255
+ }
256
+
257
+ //
258
+ // cache the response object
259
+ //
260
+ if ( ($this->use_cache == true) && ($this->cacheable($type) == true) ) {
261
+
262
+ $this->cache->put($packet_hash, $response);
263
+ }
264
+
265
+ return $response;
266
+ }
267
+
268
+ /**
269
+ * does an inverse query for the given RR; most DNS servers do not implement
270
+ * inverse queries, but they should be able to return "not implemented"
271
+ *
272
+ * @param Net_DNS2_RR $rr the RR object to lookup
273
+ *
274
+ * @return Net_DNS2_RR object
275
+ * @throws Net_DNS2_Exception
276
+ * @access public
277
+ *
278
+ */
279
+ public function iquery(Net_DNS2_RR $rr)
280
+ {
281
+ //
282
+ // make sure we have some name servers set
283
+ //
284
+ $this->checkServers(Net_DNS2::RESOLV_CONF);
285
+
286
+ //
287
+ // create an empty packet
288
+ //
289
+ $packet = new Net_DNS2_Packet_Request($rr->name, 'A', 'IN');
290
+
291
+ //
292
+ // unset the question
293
+ //
294
+ $packet->question = array();
295
+ $packet->header->qdcount = 0;
296
+
297
+ //
298
+ // set the opcode to IQUERY
299
+ //
300
+ $packet->header->opcode = Net_DNS2_Lookups::OPCODE_IQUERY;
301
+
302
+ //
303
+ // add the given RR as the answer
304
+ //
305
+ $packet->answer[] = $rr;
306
+ $packet->header->ancount = 1;
307
+
308
+ //
309
+ // check for an authentication method; either TSIG or SIG
310
+ //
311
+ if ( ($this->auth_signature instanceof Net_DNS2_RR_TSIG)
312
+ || ($this->auth_signature instanceof Net_DNS2_RR_SIG)
313
+ ) {
314
+ $packet->additional[] = $this->auth_signature;
315
+ $packet->header->arcount = count($packet->additional);
316
+ }
317
+
318
+ //
319
+ // send the packet and get back the response
320
+ //
321
+ return $this->sendPacket($packet, $this->use_tcp);
322
+ }
323
+ }
324
+
325
+ /*
326
+ * Local variables:
327
+ * tab-width: 4
328
+ * c-basic-offset: 4
329
+ * c-hanging-comment-ender-p: nil
330
+ * End:
331
+ */
332
+ ?>
includes/Net/DNS2/Socket.php ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS Library for handling lookups and updates.
6
+ *
7
+ * PHP Version 5
8
+ *
9
+ * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions
14
+ * are met:
15
+ *
16
+ * * Redistributions of source code must retain the above copyright
17
+ * notice, this list of conditions and the following disclaimer.
18
+ *
19
+ * * Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in
21
+ * the documentation and/or other materials provided with the
22
+ * distribution.
23
+ *
24
+ * * Neither the name of Mike Pultz nor the names of his contributors
25
+ * may be used to endorse or promote products derived from this
26
+ * software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
37
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
+ * POSSIBILITY OF SUCH DAMAGE.
40
+ *
41
+ * @category Networking
42
+ * @package Net_DNS2
43
+ * @author Mike Pultz <mike@mikepultz.com>
44
+ * @copyright 2010 Mike Pultz <mike@mikepultz.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
46
+ * @version SVN: $Id$
47
+ * @link http://pear.php.net/package/Net_DNS2
48
+ * @since File available since Release 0.6.0
49
+ *
50
+ */
51
+
52
+ /*
53
+ * check to see if the socket defines exist; if they don't, then define them
54
+ */
55
+ if (defined('SOCK_STREAM') == false) {
56
+ define('SOCK_STREAM', 1);
57
+ }
58
+ if (defined('SOCK_DGRAM') == false) {
59
+ define('SOCK_DGRAM', 2);
60
+ }
61
+
62
+ /**
63
+ * This is the abstract base class for the two sockets classes; this simply
64
+ * provides the class definition for the two sockets classes.
65
+ *
66
+ * @category Networking
67
+ * @package Net_DNS2
68
+ * @author Mike Pultz <mike@mikepultz.com>
69
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
70
+ * @link http://pear.php.net/package/Net_DNS2
71
+ * @see Net_DNS2_Socket_Sockets, Net_DNS2_Socket_Streams
72
+ *
73
+ */
74
+ abstract class Net_DNS2_Socket
75
+ {
76
+ protected $sock;
77
+ protected $type;
78
+ protected $host;
79
+ protected $port;
80
+ protected $timeout;
81
+
82
+ protected $local_host;
83
+ protected $local_port;
84
+
85
+ public $last_error;
86
+
87
+ /*
88
+ * type of sockets
89
+ */
90
+ const SOCK_STREAM = SOCK_STREAM;
91
+ const SOCK_DGRAM = SOCK_DGRAM;
92
+
93
+ /**
94
+ * constructor - set the port details
95
+ *
96
+ * @param integer $type the socket type
97
+ * @param string $host the IP address of the DNS server to connect to
98
+ * @param integer $port the port of the DNS server to connect to
99
+ * @param integer $timeout the timeout value to use for socket functions
100
+ *
101
+ * @access public
102
+ *
103
+ */
104
+ public function __construct($type, $host, $port, $timeout)
105
+ {
106
+ $this->type = $type;
107
+ $this->host = $host;
108
+ $this->port = $port;
109
+ $this->timeout = $timeout;
110
+ }
111
+
112
+ /**
113
+ * destructor
114
+ *
115
+ * @access public
116
+ */
117
+ public function __destruct()
118
+ {
119
+ $this->close();
120
+ }
121
+
122
+ /**
123
+ * sets the local address/port for the socket to bind to
124
+ *
125
+ * @param string $address the local IP address to bind to
126
+ * @param mixed $port the local port to bind to, or 0 to let the socket
127
+ * function select a port
128
+ *
129
+ * @return boolean
130
+ * @access public
131
+ *
132
+ */
133
+ public function bindAddress($address, $port = 0)
134
+ {
135
+ $this->local_host = $address;
136
+ $this->local_port = $port;
137
+
138
+ return true;
139
+ }
140
+
141
+ /**
142
+ * opens a socket connection to the DNS server
143
+ *
144
+ * @return boolean
145
+ * @access public
146
+ *
147
+ */
148
+ abstract public function open();
149
+
150
+ /**
151
+ * closes a socket connection to the DNS server
152
+ *
153
+ * @return boolean
154
+ * @access public
155
+ *
156
+ */
157
+ abstract public function close();
158
+
159
+ /**
160
+ * writes the given string to the DNS server socket
161
+ *
162
+ * @param string $data a binary packed DNS packet
163
+ *
164
+ * @return boolean
165
+ * @access public
166
+ *
167
+ */
168
+ abstract public function write($data);
169
+
170
+ /**
171
+ * reads a response from a DNS server
172
+ *
173
+ * @param integer &$size the size of the DNS packet read is passed back
174
+ * @param integer $max_size the max data size returned.
175
+ *
176
+ * @return mixed returns the data on success and false on error
177
+ * @access public
178
+ *
179
+ */
180
+ abstract public function read(&$size, $max_size);
181
+ }
182
+
183
+ /*
184
+ * Local variables:
185
+ * tab-width: 4
186
+ * c-basic-offset: 4
187
+ * c-hanging-comment-ender-p: nil
188
+ * End:
189
+ */
190
+ ?>
includes/Net/DNS2/Socket/Sockets.php ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * DNS