I am trying to do a mail verification using telnet and php. The whole process words fine in the terminal, but when I use php shell_exec(), it only runs upto the Telnet connection command. Once telnet is connected, the remaining telnet specific commands don't work anymore.
Is there some other way that we need to execute telnet using php?
UPDATE: I am trying to replicate this tutorial.
Here's my Code
public function mailtest(Request $request){
//Taking input email
$email = $request->input("email");
$divide = explode("#", $email);
//Find out the Domain
$server = $divide[1];
$response = shell_exec("nslookup -q=mx $server");
//Response of the nslookup
print_r($response);
$mailServerList = explode(PHP_EOL, $response);
$line = $mailServerList[4];
$serverArr = preg_split('/\s+/', $line);
$n = sizeof($serverArr);
$mailServer = $serverArr[$n-1];
//Printing out the mail server out of the nslookup response
print_r($mailServer);
//Executing Telnet command
$telnet = shell_exec("telnet $mailServer 25");
print_r("telnet response ".$telnet);
//Telnet Helo
$helo = shell_exec("Helo testing.com");
print_r("Helo response ".$helo);
//Telnet mail from
$from = shell_exec('mail from: testing#gmail.com');
print_r("MAil from response ".$from);
//Telnet RCPT to
$finalResponse = shell_exec("rcpt to: $email");
print_r("Mail to response ".$finalResponse);
}
And here's the response
Server: 10.0.80.11
Address: 10.0.80.11#53
Non-authoritative answer:
gmail.com mail exchanger = 5 gmail-smtp-in.l.google.com.
gmail.com mail exchanger = 10 alt1.gmail-smtp-in.l.google.com.
gmail.com mail exchanger = 40 alt4.gmail-smtp-in.l.google.com.
gmail.com mail exchanger = 30 alt3.gmail-smtp-in.l.google.com.
gmail.com mail exchanger = 20 alt2.gmail-smtp-in.l.google.com.
Authoritative answers can be found from:
gmail-smtp-in.l.google.com internet address = 173.194.64.27
gmail-smtp-in.l.google.com has AAAA address 2607:f8b0:4003:c02::1a
alt1.gmail-smtp-in.l.google.com internet address = 173.194.219.27
alt1.gmail-smtp-in.l.google.com has AAAA address 2607:f8b0:4002:c03::1b
alt4.gmail-smtp-in.l.google.com internet address = 64.233.190.26
alt4.gmail-smtp-in.l.google.com has AAAA address 2800:3f0:4003:c01::1b
alt3.gmail-smtp-in.l.google.com internet address = 74.125.141.26
alt3.gmail-smtp-in.l.google.com has AAAA address 2607:f8b0:400c:c06::1a
alt2.gmail-smtp-in.l.google.com internet address = 173.194.205.27
alt2.gmail-smtp-in.l.google.com has AAAA address 2607:f8b0:400d:c02::1b
gmail-smtp-in.l.google.com.telnet response Trying 2607:f8b0:4003:c02::1a...
Connected to gmail-smtp-in.l.google.com.
Escape character is '^]'.
Helo response
MAil from response No message, no subject; hope that's ok
Mail to response
shell_exec is not suitable for that (see Ulrich's explanation).
fsockopen should do the trick.
$fp = #fsockopen('yourMailServer.com', 9001);
if ($fp) {
fwrite($fp, "username\n");
fwrite($fp, "password\n");
while ($line = fread($fp, 2048)) {
// do things with $line
}
} else {
//return error
}
After taking some reference from #Lavi's answer, this is how I managed to solve the situation. fputs did the trick, instead of fwrite
$connect = #fsockopen($mailServer, 25);
if($connect){
fputs ($connect , "HELO $mailServer\r\n");
$out = fgets ($connect, 1024);
$details .= $out."\n";
fputs ($connect , "MAIL FROM: <$fromemail>\r\n");
//$from = fgets ($connect, 1024);
fputs ($connect , "RCPT TO: <$toemail>\r\n");
//$to = fgets ($connect, 1024);
fputs ($connect , "QUIT");
fclose($connect);
}
shell_exec() starts a new process. It first starts a shell which then executes the given string as commands. You can not use multiple shell_exec() commands to interact with the same shell, like remote-controlling a terminal.
What I would do in your case is to try to build on existing code. For example, there are a bunch of existing PHP SMTP libraries. I'm pretty sure that at least one of them will be able to do what you want or at least show you a way in which you could implement the missing features.
If you really insist on rolling your own stuff, check out the existing answer for e.g. interacting with command line program or PHP's expect module. Unless absolutely needed, I'd avoid this though, because it is inefficient. Also, webservers are often configured to disallow starting new processes for security reasons, so if your code works when you run it from the commandline but not inside the webserver, keep this difference in mind.
Related
i want to validate email address is valid or not through smtp
I can't validate emails in codeigniter.
this is Error
fwrite(): send of 34 bytes failed with errno=10054 An existing
connection was forcibly closed by the remote host.
This method check whether the email actually exist or not
i have got two same error in this code in different lines
function isValidEmail($email){
$result=false;
# BASIC CHECK FOR EMAIL PATTERN WITH REGULAR EXPRESSION
if(!preg_match('/^[_A-z0-9-]+((\.|\+)[_A-z0-9-]+)*#[A-z0-9-]+(\.[A-z0-9-]+)*(\.[A-z]{2,4})$/',$email))
return $result;
# MX RECORD CHECK
list($name, $domain)=explode('#',$email);
if(!checkdnsrr($domain,'MX'))
return $result;
# SMTP QUERY CHECK
$max_conn_time = 30;
$sock='';
$port = 25;
$max_read_time = 5;
$users=$name;
# retrieve SMTP Server via MX query on domain
$hosts = array();
$mxweights = array();
getmxrr($domain, $hosts, $mxweights);
$mxs = array_combine($hosts, $mxweights);
asort($mxs, SORT_NUMERIC);
#last fallback is the original domain
$mxs[$domain] = 100;
$timeout = $max_conn_time / count($mxs);
# try each host
while(list($host) = each($mxs)) {
#connect to SMTP server
if($sock = fsockopen($host, $port, $errno, $errstr, (float) $timeout)){
stream_set_timeout($sock, $max_read_time);
break;
}
}
# did we get a TCP socket
if($sock) {
$reply = fread($sock, 2082);
preg_match('/^([0-9]{3}) /ims', $reply, $matches);
$code = isset($matches[1]) ? $matches[1] : '';
if($code != '220') {
# MTA gave an error...
return $result;
}
# initiate smtp conversation
$msg="HELO ".$domain;
fwrite($sock, $msg."\r\n");
$reply = fread($sock, 2082);
# tell of sender
$msg="MAIL FROM: <".$name.'#'.$domain.">";
fwrite($sock, $msg."\r\n");
$reply = fread($sock, 2082);
#ask of recepient
$msg="RCPT TO: <".$name.'#'.$domain.">";
fwrite($sock, $msg."\r\n");
$reply = fread($sock, 2082);
#get code and msg from response
preg_match('/^([0-9]{3}) /ims', $reply, $matches);
$code = isset($matches[1]) ? $matches[1] : '';
if($code == '250') {
#you received 250 so the email address was accepted
$result=true;
}elseif($code == '451' || $code == '452') {
#you received 451 so the email address was greylisted
#_(or some temporary error occured on the MTA) - so assume is ok
$result=true;
}else{
$result=false;
}
#quit smtp connection
$msg="quit";
fwrite($sock, $msg."\r\n");
# close socket
fclose($sock);
}
return $result;
}
$email='test1221s#gmail.com';
if(isValidEmail($email))
echo "**** EMAIL EXISTS ****";
else
echo "**** NOT A VALID EMAIL ****";
This method check whether the email actually exist or not
You can't do that, and the other side doesn't want to talk to you anymore because you tried.
In the past, crawlers would harvest email addresses by asking the server if user#domain.com exists. Then user1#domain.com. Then user2#domain.com, etc.
They would then end up with a list of valid users to spam.
Since then, mail servers have become much less open and "chatty" and won't respond to these queries and will in fact ban your address after a number of failures.
All you can do is send the actual email and handle the bounce if it's un-deliverable. If you insist on "checking" email addresses to see if they're good, you'll find that you soon have a blacklisted IP address.
I have this python code:
from socket import *
import threading
import thread
import time
import json
def handler(clientsock,addr):
while 1:
time.sleep(2)
data = clientsock.recv(65535);
if not data:
break
object = json.loads(data)
object['status'] = 1
object['timestamp'] = time.time()
output = json.dumps(object)
msg = output
clientsock.send(msg)
clientsock.close()
if __name__ == '__main__':
HOST = '192.168.0.28'
PORT = 5555
BUFSIZ = 65535
ADDR = (HOST, PORT)
serversock = socket(AF_INET, SOCK_STREAM)
serversock.bind(ADDR)
serversock.listen(5)
while 1:
print 'waiting for connection...'
clientsock, addr = serversock.accept()
print '...connected from: ', addr
thread.start_new_thread(handler, (clientsock, addr))
and this PHP code:
<?php
/**
*
* PHP JSON Echo Server client
*
*/
// python server socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '192.168.0.28', 5555);
//Create a message, and send it to the server on $socket.
$data = array(
'username' => 'sysadmin',
'key' => '093ufj408xr0289u3r0x9u2m309x',
'action' => 'login',
);
$json = json_encode($data);
socket_send($socket, $json, strlen($json), MSG_EOF);
$data = socket_read($socket, 65535);
$object = json_decode($data);
if($object->status) {
echo '<p>Data received successfully.';
} else {
echo '<p>Error. Data not read correctly!';
}
echo '<p>'.$data;
//Close the socket.
socket_close($socket);
?>
If I run it in my local network it works without a problem. But when I execute the PHP script on an external hosting it doesn't work anymore. I've changed the IP address to my WAN IP address and even to the DNS offered by the ISP. Nothing works.
This is the output:
Warning: socket_connect(): unable to connect [111]: Connection refused in /home/usr/public_html/webclient.php on line 9
Warning: socket_send(): unable to write to socket [32]: Broken pipe in /home/usr/public_html/webclient.php on line 17
Warning: socket_read(): unable to read from socket [107]: Transport endpoint is not connected in /home/usr/public_html/webclient.php on line 18
Error. Data not read correctly!
I tried scanning for open ports with this service: http://www.ipfingerprints.com/portscan.php and port 5555 is open. I also got a message from the server:
waiting for connection...
...connected from: ('5.79.68.210', 36080)
Where is the problem?
on this code :
print '...connected from: ', addr
you cant use this code, for know open port you need use this code:
print '...connect from: ' + addr[0] + ':' + str(addr[1])
only that
and you arnt using the sockets coorectly:
serversock = socket(AF_INET, SOCK_STREAM)
use this its will be better:
serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
I noticed that my server has been returning this error when trying to send email to an invalid domain:
Standard Message: Failed to set sender: user#invaliddomain.coom [SMTP: Invalid response code received from server (code: 553, response: 5.1.8 ... Domain of sender address user#invaliddomain.coom does not exist)]
Standard Code: 10004
DBMS/User Message:
DBMS/Debug Message:
Is there a way to check the domain first before attempting to send the email? I have a feeling I could also handle this on the SMTP server end by squelching this error, but I like the idea of being able to test an email domain first before sending it. Thanks for your ideas!
Here is the pertinent code just for reference (variables are filtered in from a form):
$headers['To'] = $to_address;
$headers['From'] = $from;
$headers['Reply-To'] = $from;
$headers['Subject'] = $subject;
$this->setHTMLBody($body);
$body = $this->get(array('text_charset' => 'utf-8'));
$headers = $this->headers($headers, true);
$message =& Mail::factory('smtp');
$mail = $message->send($to_address,$headers,$body);
You could use Net_DNS2 to determine if the domain exists and if so, send the email on it's merry way.
include "Net/DNS2.php";
$r = new Net_DNS2_Resolver();
try {
$result = $r->query($domain, 'MX');
} catch(Net_DNS2_Exception $e) {
$result = null;
}
if ($result !== null) {
// send email...
}
Naturally, I'd suggest some level of caching so you aren't repeating lookups.
I know i might gonna so many down vote but please help me through this as i nearly there. I have below code.
<?php
exec("mode COM1 BAUD=9600 PARITY=N data=8 stop=1 xon=off");
$fp = fopen ("\\.\com1", "r+");
//$fp = dio_open('COM5:', O_RDWR | O_NOCTTY | O_NONBLOCK);
if (!$fp)
{
echo "Uh-oh. Port not opened.";
}
else
{
$string = "AT+CMGF=1";
$string = $string."OK";
$string = $string."AT+CMGS='+44XXXXX'";
$string = $string."> Hello World?<Ctrl>+<Z>";
$string = $string."+CMGS: 44";
$string = $string."OK";
fputs ($fp, $string );
echo $string."\n";
fclose ($fp);
}
?>
above code is outputting AT+CMGF=1OKAT+CMGS='+44XXXX'> Hello World?++CMGS: 44OK but not actually sending any message to that number.
I have device is attached with PC which has SIM card in it.
How can I do this?
From what I know of AT commands, is that it is a dialogue. You have to send AT+CMGF=1 then wait for the modem to send OK, send the next command etcetera.
You are now sending everything, including the modem's responses in one string.
More information (as always) on Wikipedia: http://en.wikipedia.org/wiki/Hayes_command_set
The code should be along the lines of (off the top of my head, not tested):
$string = "AT+CMGF=1";
fputs($fp, $string);
$r = fgets($fp);
if ($r == "OK") {
$string = "AT+CMGS='+44XXXXX'";
fputs($fp, $string);
$r = $fgets($fp);
... etc ...
}
I want a PHP script which allows you to ping an IP address and a port number (ip:port). I found a similar script but it works only for websites, not ip:port.
<?php
function ping($host, $port, $timeout)
{
$tB = microtime(true);
$fP = fSockOpen($host, $port, $errno, $errstr, $timeout);
if (!$fP) { return "down"; }
$tA = microtime(true);
return round((($tA - $tB) * 1000), 0)." ms";
}
//Echoing it will display the ping if the host is up, if not it'll say "down".
echo ping("www.google.com", 80, 10);
?>
I want this for a game server.
The idea is that I can type in the IP address and port number, and I get the ping response.
I think the answer to this question pretty much sums up the problem with your question.
If what you want to do is find out whether a given host will accept
TCP connections on port 80, you can do this:
$host = '193.33.186.70';
$port = 80;
$waitTimeoutInSeconds = 1;
if($fp = fsockopen($host,$port,$errCode,$errStr,$waitTimeoutInSeconds)){
// It worked
} else {
// It didn't work
}
fclose($fp);
For anything other than TCP it will be more difficult (although since
you specify 80, I guess you are looking for an active HTTP server, so
TCP is what you want). TCP is sequenced and acknowledged, so you will
implicitly receive a returned packet when a connection is successfully
made. Most other transport protocols (commonly UDP, but others as
well) do not behave in this manner, and datagrams will not be
acknowledged unless the overlayed Application Layer protocol
implements it.
The fact that you are asking this question in this manner tells me you
have a fundamental gap in your knowledge on Transport Layer protocols.
You should read up on ICMP and TCP, as well as the OSI Model.
Also, here's a slightly cleaner version to ping to hosts.
// Function to check response time
function pingDomain($domain){
$starttime = microtime(true);
$file = fsockopen ($domain, 80, $errno, $errstr, 10);
$stoptime = microtime(true);
$status = 0;
if (!$file) $status = -1; // Site is down
else {
fclose($file);
$status = ($stoptime - $starttime) * 1000;
$status = floor($status);
}
return $status;
}
In case the OP really wanted an ICMP-Ping, there are some proposals within the User Contributed Notes to socket_create() [link], which use raw sockets. Be aware that on UNIX like systems root access is required.
Update: note that the usec argument has no function on windows. Minimum timeout is 1 second.
In any case, this is the code of the top voted ping function:
function ping($host, $timeout = 1) {
/* ICMP ping packet with a pre-calculated checksum */
$package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost";
$socket = socket_create(AF_INET, SOCK_RAW, 1);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));
socket_connect($socket, $host, null);
$ts = microtime(true);
socket_send($socket, $package, strLen($package), 0);
if (socket_read($socket, 255)) {
$result = microtime(true) - $ts;
} else {
$result = false;
}
socket_close($socket);
return $result;
}
Test different ports:
$wait = 1; // wait Timeout In Seconds
$host = 'example.com';
$ports = [
'http' => 80,
'https' => 443,
'ftp' => 21,
];
foreach ($ports as $key => $port) {
$fp = #fsockopen($host, $port, $errCode, $errStr, $wait);
echo "Ping $host:$port ($key) ==> ";
if ($fp) {
echo 'SUCCESS';
fclose($fp);
} else {
echo "ERROR: $errCode - $errStr";
}
echo PHP_EOL;
}
// Ping example.com:80 (http) ==> SUCCESS
// Ping example.com:443 (https) ==> SUCCESS
// Ping example.com:21 (ftp) ==> ERROR: 110 - Connection timed out
Try this :
echo exec('ping -n 1 -w 1 72.10.169.28');
function ping($ip){
$output = shell_exec("ping $ip");
var_dump($output);
}
ping('127.0.0.1');
UPDATE:
If you pass an hardcoded IP (like in this example and most of the real-case scenarios), this function can be enough.
But since some users seem to be very concerned about safety, please remind to never pass user generated inputs to the shell_exec function:
If the IP comes from an untrusted source, at least check it with a filter before using it.
You can use exec function
exec("ping ".$ip);
here an example
You don't need any exec or shell_exec hacks to do that, it is possible to do it in PHP. The book 'You want to do WHAT with PHP?' by Kevin Schroeder, show's how.
It uses sockets and the pack() function which lets you read and write binary protocols. What you need to do is to create an ICMP packet, which you can do by using the 'CCnnnA*' format to create your packet.
socket_create needs to be run as root on a UNIX system with;
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
If you want to send ICMP packets in php you can take a look at this Native-PHP ICMP ping implementation, but I didn't test it.
EDIT:
Maybe the site was hacked because it seems that the files got deleted, there is copy in archive.org but you can't download the tar ball file, there are no contact email only contact form, but this will not work at archive.org, we can only wait until the owner will notice that sit is down.