5

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 
Parthapratim Neog
  • 4,352
  • 6
  • 43
  • 79

3 Answers3

4

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    
}
Lavi Avigdor
  • 4,092
  • 3
  • 25
  • 28
  • basically I want to do a `telnet myMailServer.com 25` to start the connection, and then start with `Helo hi` and so on as shown in this [Tutorial](https://www.webdigi.co.uk/blog/2009/how-to-check-if-an-email-address-exists-without-sending-an-email/). I tried to use `fsockopen` but it didn't seem to work. Can you check the tutorial once and see how I should approach with `fsockopen` or whatever way you think would serve the purpose? – Parthapratim Neog Nov 29 '15 at 11:37
  • For each green line in the tutorial, you should invoke a fwrite command. And for each blue line you should read (and act upon) the $line param inside the while loop. – Lavi Avigdor Nov 29 '15 at 11:42
  • So once, the `@fsockopen('yourMailServer.com', 25);` is successful, I start off with `telnet yourMailServer.com 25`? or does the `fsockopen` command serve the same purpose? – Parthapratim Neog Nov 29 '15 at 11:44
  • fsockopen replaces the telnet. it opens a socket. – Lavi Avigdor Nov 29 '15 at 11:46
2

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);
}
Parthapratim Neog
  • 4,352
  • 6
  • 43
  • 79
1

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.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55