-1

So, I was trying to use strpos to test if a string existed in a variable, but in all my attempts to make the if statement work, it was not succeeding, so I went about outputting the string and trying to find the point where strpos detected it, but it was not though it was clearly there! In this case I am searching an SMTP error output for the Gmail SMTP error code.
I know how to fix the error, but I want my system to be able to parse smtp errors and report them to my users...

PHP Code:

$Request = RequestPasswordReset($_POST["email"]);
echo $Request;
echo "<br>Position of Error Code: " . strpos($Request, "gsmtp SMTP code: 550");
die();
if($Request === "SUCCESS") {
    DisplayError("Password Reset Successful", "We have sent a email that contains a link to reset your password.", "/account/resetpassword.php");
} else if($Request === "USER_NOT_FOUND") {
    DisplayError("Password Reset Request Failed", "The specified email is not tied to any accounts in our system.", "/account/resetpassword.php");
} else if(strpos($Request, "gsmtp SMTP code: 550") !== false) {
    DisplayError("Password Reset Request Failed", "The mail was blocked by our relay due to IPs being not whitelisted.", "/account/resetpassword.php");
} else {
    DisplayError("Password Reset Request Failed", "The request failed for an unknown reason.", "/account/resetpassword.php");
}

Text Output:
It does actually repeat itself, I echoed out the $Request twice and it did the following twice exactly

The following From address failed: XXXXXXX : MAIL FROM command failed,Invalid credentials for relay [XXXXXXX]. The IP address you've registered in your G Suite SMTP Relay service doesn't match domain of the account this email is being sent from. If you are trying to relay mail from a domain that isn't registered under your G Suite account or has empty envelope-from, you must configure your mail server either to use SMTP AUTH to identify the sending domain or to present one of your domain names in the HELO or EHLO command. For more information, please visit https://support.google.com/a/answer/6140680#invalidcred r126sm1314271qke.4 - gsmtp ,550,5.7.1SMTP server error: MAIL FROM command failed Detail: Invalid credentials for relay [XXXXXXX]. The IP address you've registered in your G Suite SMTP Relay service doesn't match domain of the account this email is being sent from. If you are trying to relay mail from a domain that isn't registered under your G Suite account or has empty envelope-from, you must configure your mail server either to use SMTP AUTH to identify the sending domain or to present one of your domain names in the HELO or EHLO command. For more information, please visit https://support.google.com/a/answer/6140680#invalidcred r126sm1314271qke.4 - gsmtp SMTP code: 550 Additional SMTP info: 5.7.1
Position of Error Code:

(EDIT) Reset Password Request Function:

function RequestPasswordReset($Email) {
// Try to Get User
$User = GetUser_Email($Email);

// Does user exist?
if($User === "NOT_FOUND") {
  return "USER_NOT_FOUND";
}

// Generate Link To Send with Email
$Link = GeneratePasswordResetLink();
$SendEmail = SendPasswordReset($User["Email"], $User["FirstName"] . $User["LastName"], $Link);

if($SendEmail !== "SUCCESS") {
  return $SendEmail;
} else {
  // WHAT IF MYSQL FAILS????? ~~~~~~~~~~~~~~~ NEED  SOLOUTION
  $PDO_Connection = CreateMySQLConnection();
  $PDO_CMD = $PDO_Connection -> prepare("UPDATE accounts SET ResetPassword=? WHERE Email=?");
    $PDO_CMD -> execute(array($Link, $User["Email"]));
  return "SUCCESS";
}
}


(EDIT) Send Password Reset Function:

$User = GetUser_ResetID($resetID);

$mail = CreateSMTPConnection();
$mail->AddAddress($targetAddress, $targetName);       // Add a recipient

$mail->IsHTML(true);                                  // Set email format to HTML
$mail->Subject = 'LitenUp Password Reset';
$mail->Body    = str_replace("https://mylitenup.net/account/resetpassword.php?ID=", ("https://mylitenup.net/account/resetpassword.php?ID=" . $resetID), file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/php/mailer/documents/resetpassword.html"));
$mail->AltBody = 'Reset Your Password: https://mylitenup.net/account/resetpassword.php?ID=' . $resetID;
$mail->XMailer = 'LitenUp Mailer';
$mail->XPriority = '1';

  try{
    $mail->send();
    return "SUCCESS";
  } catch (phpmailerException $e) {
    return $e->errorMessage();
  } catch (\Exception $e) {
    return $e->getMessage();
  }

(EDIT): I tried mb_strpos, but it is not working, so if that is what will work, why is it not working for me? I did mb_strpos($Request, "gsmtp SMTP code: 550");, but after execution it echos the request, but the Position of Error Code: line does not get echoed.

(Update 1): I really apologize for the delay, in a worst case I will extend this again with a bounty. However, you guys were right! When I first had the error, I outputted it and just copied the line "gsmtp SMTP code: 550", but after doing the tag there appears to be a new line of some sort. You can see in the output that the line should be something more like "gsmtp" + + " SMTP code: 550", but I am not sure what the line break should be. I tried
and \n.

Sean Mitchell
  • 447
  • 2
  • 21
  • I am very sorry I did not format the text output as Stack Overflow code, but every time I tried it became one line. – Sean Mitchell Jan 20 '18 at 16:45
  • 1
    Could this be a multibyte character set issue? Try [`mb_strpos()`](http://php.net/manual/en/function.mb-strpos.php) – RiggsFolly Jan 20 '18 at 16:52
  • @RiggsFolly I will try that, but why would that be an issue? – Sean Mitchell Jan 20 '18 at 16:58
  • Only thing I can think of as the code looks like it shoudl work – RiggsFolly Jan 20 '18 at 16:58
  • @RiggsFolly Just tried it and now the "Position of Error Code:" line is completely gone! Is there a library I am missing? Code is Currently " echo "
    Position of Error Code: " . mb_strpos($Request, "gsmtp SMTP code: 550");"
    – Sean Mitchell Jan 20 '18 at 16:59
  • @SeanMitchell You'd of most likely have been downvoted for it Sean. I may have done you a favor here. – Funk Forty Niner Jan 20 '18 at 17:35
  • provide a `RequestPasswordReset()` content – Deadooshka Jan 20 '18 at 17:59
  • I'd like to second the suggestion that it's a char encoding / multi-byte-char issue. If the inbound string is encoded with a multi-byte encoding (eg: UTF-8) then strpos won't be reliable as it deals with bytes, not chars. Unfortunately despite you posting a lot of code (good) it's not that useful as it's not stand-alone and relies on external services to work, so... we can't test it. It might be an idea to read sscce.org for good advice as to how to post code when asking for help. But... yeah... use the multi-byte aware functions and see if that sorts you out. – Adam Cameron Jan 20 '18 at 20:50
  • @AdamCameron I tried doing mb_strpos but now the whole line of code just disappears... – Sean Mitchell Jan 20 '18 at 22:56
  • I have no idea how to interpret "the whole line of code just disappears". Code doesn't _disappear_. What do you mean? – Adam Cameron Jan 21 '18 at 02:41
  • "Position of Error Code" does not display – Sean Mitchell Jan 21 '18 at 05:11
  • I just copy and pasted the output of `$Request` from your question and ran the `strpos()` function against it and got the result "**1278**". – But those new buttons though.. Jan 25 '18 at 04:39
  • are you tried with 'Case-Insensitive' ? `stripos($Request, "gsmtp SMTP code: 550");` – Mochamad Arifin Jan 25 '18 at 13:05
  • Can you replace the code where you echo the Request: echo $Request; with echo '
    ' . $Request . '
    '; Maybe what you see in the browser has the whitespaces concentrated.
    – Jannes Botis Jan 26 '18 at 09:07
  • The string may have some special characters. Could you `file_put_contents("output.txt", $Request)` and `hexdump -C output.txt` or use a PHP function to display the content as hexadecimal form (such as https://stackoverflow.com/questions/14674834/php-convert-string-to-hex-and-hex-to-string), please ? – Syscall Jan 26 '18 at 18:00
  • @MochamadArifin and others I will test your solutions within the next 24 hours, I sincerely apologize for the delay, but I am off site as of right now. I have to go in tomorrow anyway, so I will test this then when there. – Sean Mitchell Jan 27 '18 at 05:30
  • I apologize for having forgot about this. I am testing your code today, I have been swamped lately. – Sean Mitchell Jan 31 '18 at 12:28
  • Updated! I really do apologize, there is no excuse in all honesty. – Sean Mitchell Jan 31 '18 at 12:53
  • To know the line-end type, you have to display the string into a hexadecimal form or using `ord()` on each characters. – Syscall Jan 31 '18 at 14:25
  • @Syscall I converted it to HEX and I got HEX value 20. I looked at a table and it said it translated to "DC4", but I do not know how to add that to the PHP strpos. – Sean Mitchell Jan 31 '18 at 14:27
  • @Syscall Correction it is a new line hex and a space hex, but it is still not working as planned even when doing \n and space. – Sean Mitchell Jan 31 '18 at 14:36
  • And, why not just `strpos($Request, 'SMTP code:')` ? And if required, `strrpos()` to find last `"gsmtp"` with the position found with `strpos()` ? – Syscall Jan 31 '18 at 15:00
  • @Syscall I am parsing other data out in the future, so just making my life easier and giving up parsing quality is not an option. – Sean Mitchell Jan 31 '18 at 16:10
  • Try "\r\n" instead of "\n". – Jannes Botis Jan 31 '18 at 21:15
  • To clarify: what is the message format that you want to display and why are you using stripos function? – Praneeth Nidarshan Feb 01 '18 at 01:20

2 Answers2

3

The best solution would be to take the time to isolate exactly what character(s) is in that white-space.

Until you do that, you can just use regex to gloss over whatever is in there.

Change:

} else if(strpos($Request, "gsmtp SMTP code: 550") !== false) {

to:

} elseif(preg_match("/gsmtp\s+SMTP\s+code:\s+550/",$Request)) {
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • Sadly you did not come in time for the bounty, but your answer is great since regex will be more dynamic if Google changes any of their smtp error codes! – Sean Mitchell Feb 04 '18 at 02:44
1

My best guess:

You're outputting to HTML, so it's possible that your CRLFs/LFs are rendering as spaces. I'd enclose your echo statements with <pre>...</pre> tags to see if it's the case. strpos would fail because you're searching for a space character where it's actually a CRLF/LF.

Peter Li
  • 410
  • 1
  • 3
  • 13