Skip to content

Commit 0989b3d

Browse files
authored
Count A/AAAA, MX and PTR requests separately, fixes #25 (#28)
1 parent 88a5285 commit 0989b3d

11 files changed

+404
-29
lines changed

src/DNSRecordGetter.php

+30-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
class DNSRecordGetter implements DNSRecordGetterInterface
1414
{
1515
protected $requestCount = 0;
16+
protected $requestMXCount = 0;
17+
protected $requestPTRCount = 0;
1618

1719
/**
1820
* @param $domain string The domain to get SPF record
@@ -94,7 +96,7 @@ public function resolvePtr($ipAddress)
9496
return $e['target'];
9597
}, dns_get_record($revIp, DNS_PTR));
9698

97-
return array_slice($revs, 0, 10);
99+
return $revs;
98100
}
99101

100102
public function exists($domain)
@@ -106,14 +108,39 @@ public function exists($domain)
106108
}
107109
}
108110

111+
/**
112+
* @codeCoverageIgnore
113+
*/
109114
public function resetRequestCount()
110115
{
111-
$this->requestCount = 0;
116+
trigger_error('DNSRecordGetterInterface::resetRequestCount() is deprecated. Please use resetRequestCounts() instead', E_USER_DEPRECATED);
117+
$this->resetRequestCounts();
112118
}
113119

114120
public function countRequest()
115121
{
116-
if (++$this->requestCount > 10) {
122+
if ($this->requestCount++ == 10) {
123+
throw new DNSLookupLimitReachedException();
124+
}
125+
}
126+
127+
public function resetRequestCounts()
128+
{
129+
$this->requestCount = 0;
130+
$this->requestMXCount = 0;
131+
$this->requestPTRCount = 0;
132+
}
133+
134+
public function countMxRequest()
135+
{
136+
if (++$this->requestMXCount > 10) {
137+
throw new DNSLookupLimitReachedException();
138+
}
139+
}
140+
141+
public function countPtrRequest()
142+
{
143+
if (++$this->requestPTRCount > 10) {
117144
throw new DNSLookupLimitReachedException();
118145
}
119146
}

src/DNSRecordGetterDirect.php

+40-13
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ class DNSRecordGetterDirect implements DNSRecordGetterInterface
1515
{
1616

1717
protected $requestCount = 0;
18+
protected $requestMXCount = 0;
19+
protected $requestPTRCount = 0;
1820
protected $nameserver = "8.8.8.8";
1921
protected $port = 53;
2022
protected $timeout = 30;
@@ -140,7 +142,7 @@ public function resolvePtr($ipAddress)
140142
return $e['target'];
141143
}, $this->dns_get_record($revIp, "PTR"));
142144

143-
return array_slice($revs, 0, 10);
145+
return $revs;
144146
}
145147

146148
public function exists($domain)
@@ -152,18 +154,6 @@ public function exists($domain)
152154
}
153155
}
154156

155-
public function resetRequestCount()
156-
{
157-
$this->requestCount = 0;
158-
}
159-
160-
public function countRequest()
161-
{
162-
if (++$this->requestCount > 10) {
163-
throw new DNSLookupLimitReachedException();
164-
}
165-
}
166-
167157
public function dns_get_record($question, $type)
168158
{
169159

@@ -248,4 +238,41 @@ public function dns_get_record($question, $type)
248238

249239
return $response;
250240
}
241+
242+
/**
243+
* @codeCoverageIgnore
244+
*/
245+
public function resetRequestCount()
246+
{
247+
trigger_error('DNSRecordGetterInterface::resetRequestCount() is deprecated. Please use resetRequestCounts() instead', E_USER_DEPRECATED);
248+
$this->resetRequestCounts();
249+
}
250+
251+
public function countRequest()
252+
{
253+
if (++$this->requestCount > 10) {
254+
throw new DNSLookupLimitReachedException();
255+
}
256+
}
257+
258+
public function resetRequestCounts()
259+
{
260+
$this->requestCount = 0;
261+
$this->requestMXCount = 0;
262+
$this->requestPTRCount = 0;
263+
}
264+
265+
public function countMxRequest()
266+
{
267+
if (++$this->requestMXCount > 10) {
268+
throw new DNSLookupLimitReachedException();
269+
}
270+
}
271+
272+
public function countPtrRequest()
273+
{
274+
if (++$this->requestPTRCount > 10) {
275+
throw new DNSLookupLimitReachedException();
276+
}
277+
}
251278
}

src/DNSRecordGetterInterface.php

+49
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,62 @@
77
namespace Mika56\SPFCheck;
88

99

10+
use Mika56\SPFCheck\Exception\DNSLookupException;
11+
use Mika56\SPFCheck\Exception\DNSLookupLimitReachedException;
12+
1013
interface DNSRecordGetterInterface
1114
{
15+
/**
16+
* @param $domain
17+
* @return string[]
18+
* @throws DNSLookupException
19+
*/
1220
public function getSPFRecordForDomain($domain);
21+
1322
public function resolveA($domain, $ip4only = false);
23+
1424
public function resolveMx($domain);
25+
1526
public function resolvePtr($ipAddress);
27+
28+
/**
29+
* @param $domain
30+
* @return boolean
31+
* @throws DNSLookupException
32+
*/
1633
public function exists($domain);
34+
35+
/**
36+
* @return void
37+
* @deprecated {@see resetRequestCounts}
38+
* @codeCoverageIgnore
39+
*/
1740
public function resetRequestCount();
41+
42+
/**
43+
* Reset all request counters (A/AAAA, MX, PTR)
44+
* @return void
45+
*/
46+
public function resetRequestCounts();
47+
48+
/**
49+
* Count a A/AAAA request
50+
* @throws DNSLookupLimitReachedException
51+
* @return void
52+
*/
1853
public function countRequest();
54+
55+
/**
56+
* Count an MX request
57+
* @throws DNSLookupLimitReachedException
58+
* @return void
59+
*/
60+
public function countMxRequest();
61+
62+
/**
63+
* Count a PTR request
64+
* @throws DNSLookupLimitReachedException
65+
* @return void
66+
*/
67+
public function countPtrRequest();
1968
}

src/SPFCheck.php

+17-4
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ protected function doIsIPAllowed($ipAddress, $domain, $resetRequestCount)
7676
$this->redirect = null;
7777
if ($resetRequestCount) {
7878
$this->voidLookup = 0;
79-
$this->DNSRecordGetter->resetRequestCount();
79+
$this->DNSRecordGetter->resetRequestCounts();
8080
}
8181

8282
// Handle IPv4 address in IPv6 format
@@ -92,6 +92,12 @@ protected function doIsIPAllowed($ipAddress, $domain, $resetRequestCount)
9292
return $result;
9393
}
9494

95+
/**
96+
* @param $ipAddress
97+
* @param $domain
98+
* @return bool|string
99+
* @throws DNSLookupException
100+
*/
95101
private function doCheck($ipAddress, $domain)
96102
{
97103
try {
@@ -141,6 +147,14 @@ private function doCheck($ipAddress, $domain)
141147
return self::RESULT_NEUTRAL;
142148
}
143149

150+
/**
151+
* @param $ipAddress
152+
* @param $part
153+
* @param $matchingDomain
154+
* @return bool
155+
* @throws DNSLookupLimitReachedException
156+
* @throws DNSLookupException
157+
*/
144158
protected function ipMatchesPart($ipAddress, $part, $matchingDomain)
145159
{
146160
$qualifier = substr($part, 0, 1);
@@ -242,10 +256,8 @@ protected function ipMatchesPart($ipAddress, $part, $matchingDomain)
242256
$validIpAddresses = [];
243257
$this->DNSRecordGetter->countRequest();
244258
$mxServers = $this->DNSRecordGetter->resolveMx($domain);
245-
if (count($mxServers) > 10) {
246-
return self::RESULT_PERMERROR;
247-
}
248259
foreach ($mxServers as $mxServer) {
260+
$this->DNSRecordGetter->countMxRequest();
249261
if (false !== filter_var($mxServer, FILTER_VALIDATE_IP)) {
250262
$validIpAddresses[] = $mxServer;
251263
} else {
@@ -277,6 +289,7 @@ protected function ipMatchesPart($ipAddress, $part, $matchingDomain)
277289
$ptrRecords = $this->DNSRecordGetter->resolvePtr($ipAddress);
278290
$validatedSendingDomainNames = array();
279291
foreach ($ptrRecords as $ptrRecord) {
292+
$this->DNSRecordGetter->countPtrRequest();
280293
$ptrRecord = strtolower($ptrRecord);
281294
$ipAddresses = $this->DNSRecordGetter->resolveA($ptrRecord);
282295
if (in_array($ipAddress, $ipAddresses)) {

tests/DNSRecordGetterIssue3.php

+26-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
class DNSRecordGetterIssue3 implements DNSRecordGetterInterface
1414
{
1515
protected $requestCount = 0;
16+
protected $requestMXCount = 0;
17+
protected $requestPTRCount = 0;
1618

1719
protected $spfRecords = [
1820
'domain.com' => 'v=spf1 include:domain.com ~all',
@@ -49,12 +51,34 @@ public function exists($domain)
4951

5052
public function resetRequestCount()
5153
{
52-
$this->requestCount = 0;
54+
trigger_error('DNSRecordGetterInterface::resetRequestCount() is deprecated. Please use resetRequestCounts() instead', E_USER_DEPRECATED);
55+
$this->resetRequestCounts();
5356
}
5457

5558
public function countRequest()
5659
{
57-
if (++$this->requestCount == 10) {
60+
if (++$this->requestCount > 10) {
61+
throw new DNSLookupLimitReachedException();
62+
}
63+
}
64+
65+
public function resetRequestCounts()
66+
{
67+
$this->requestCount = 0;
68+
$this->requestMXCount = 0;
69+
$this->requestPTRCount = 0;
70+
}
71+
72+
public function countMxRequest()
73+
{
74+
if (++$this->requestMXCount > 10) {
75+
throw new DNSLookupLimitReachedException();
76+
}
77+
}
78+
79+
public function countPtrRequest()
80+
{
81+
if (++$this->requestPTRCount > 10) {
5882
throw new DNSLookupLimitReachedException();
5983
}
6084
}

tests/DNSRecordGetterIssue7.php

+26-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
class DNSRecordGetterIssue7 implements DNSRecordGetterInterface
1313
{
1414
protected $requestCount = 0;
15+
protected $requestMXCount = 0;
16+
protected $requestPTRCount = 0;
1517

1618
protected $spfRecords = [
1719
];
@@ -39,12 +41,34 @@ public function exists($domain)
3941

4042
public function resetRequestCount()
4143
{
42-
$this->requestCount = 0;
44+
trigger_error('DNSRecordGetterInterface::resetRequestCount() is deprecated. Please use resetRequestCounts() instead', E_USER_DEPRECATED);
45+
$this->resetRequestCounts();
4346
}
4447

4548
public function countRequest()
4649
{
47-
if (++$this->requestCount == 10) {
50+
if (++$this->requestCount > 10) {
51+
throw new DNSLookupLimitReachedException();
52+
}
53+
}
54+
55+
public function resetRequestCounts()
56+
{
57+
$this->requestCount = 0;
58+
$this->requestMXCount = 0;
59+
$this->requestPTRCount = 0;
60+
}
61+
62+
public function countMxRequest()
63+
{
64+
if (++$this->requestMXCount > 10) {
65+
throw new DNSLookupLimitReachedException();
66+
}
67+
}
68+
69+
public function countPtrRequest()
70+
{
71+
if (++$this->requestPTRCount > 10) {
4872
throw new DNSLookupLimitReachedException();
4973
}
5074
}

tests/DNSRecordGetterOpenSPF.php

+26-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class DNSRecordGetterOpenSPF implements DNSRecordGetterInterface
1616
{
1717
protected $data;
1818
protected $requestCount;
19+
protected $requestMXCount = 0;
20+
protected $requestPTRCount = 0;
1921

2022
public function __construct($data)
2123
{
@@ -145,12 +147,34 @@ public function exists($domain)
145147

146148
public function resetRequestCount()
147149
{
148-
$this->requestCount = 0;
150+
trigger_error('DNSRecordGetterInterface::resetRequestCount() is deprecated. Please use resetRequestCounts() instead', E_USER_DEPRECATED);
151+
$this->resetRequestCounts();
149152
}
150153

151154
public function countRequest()
152155
{
153-
if (++$this->requestCount == 11) {
156+
if (++$this->requestCount > 10) {
157+
throw new DNSLookupLimitReachedException();
158+
}
159+
}
160+
161+
public function resetRequestCounts()
162+
{
163+
$this->requestCount = 0;
164+
$this->requestMXCount = 0;
165+
$this->requestPTRCount = 0;
166+
}
167+
168+
public function countMxRequest()
169+
{
170+
if (++$this->requestMXCount > 10) {
171+
throw new DNSLookupLimitReachedException();
172+
}
173+
}
174+
175+
public function countPtrRequest()
176+
{
177+
if (++$this->requestPTRCount > 10) {
154178
throw new DNSLookupLimitReachedException();
155179
}
156180
}

0 commit comments

Comments
 (0)