comparing code in Associative Arrays to hard coded values - php

I have a text file with the following values which would be used as a username and password
root=>user
roots=>password
blabla=>moonbeam
help=>me
Code for a function validateUser in a file validateUser.php
function validateUser($username, $password)
{
$filename = 'userCreds.txt';
$file = fopen($filename, "r");
if($file==false)
{
echo"Error opening file";
exit();
}
$i=0;
static $Credentials = array();
foreach (file($filename) as $line)
{
list($key,$value) = explode("=>",$line,2) + array(NULL,NULL);
if($value !== NULL)
{
$Credentials[$key] = $value;
}
}
print_r($Credentials);
echo "<br>";
//static $Credentials = array("root"=>"user","rtam"=>"password","q"=>"continuum");
if(array_key_exists($username, $Credentials))
{
echo "$Credentials[$username] <br>";
echo "$password <br>";
if($Credentials[$username] == $password)
{
return TRUE;
}
else
{
echo $Credentials[$username]," is not equal to ",$password,"<br>";
return FALSE;
}
}
else return FALSE;
}
Code for the main file:
<?php
include_once "validateUser.php";
$username = "root";
$password = "user";
if(validateUser($username,$password))
{
echo "<h2>Welcome! <br></h2>";
}
else
{
echo "Try again <br>";
}
?>
The values for $username and password are hardcoded from the beginning for testing purposes.
The problem I have, is when I get to comparing the username and password from the text file and comparing the two, they don't match.
Even when I print out the two values i.e. $password and $Credentials[$username], I get equal values on screen but the if statement doesn't recognize it using if($Credentials[$username] == $password).
What am I doing wrong?

please try to trim the values in your validateuser function - wouldn't be the first time a \n or \t or simple space caught me out.
if($value !== NULL)
{
$Credentials[trim($key)] = trim($value);
}
If that's not the case then maybe you can use regex to strip our any non alphanumeric chars from username and password.
eg
$key = preg_replace('/[^(\x20-\x7F)]*/','', $key);
$value = preg_replace('/[^(\x20-\x7F)]*/','', $value);

Related

Login checks user and passowrd from json file(php). How to read file from json file

I have that problem that just throws me a mistake to try again, it doesn't check json file.
here is my php code:
<?php
if (isset($_SERVER["PHP_AUTH_USER"]) && isset($_SERVER["PHP_AUTH_PW"])) {
$json = file_get_contents("user-data.json");
$json_data = json_decode($json, true);
$user = $_SERVER["PHP_AUTH_USER"];
$pw = $_SERVER["PHP_AUTH_PW"];
$flag =false;
foreach ($json_data as $key => $value) {
if ($value['PHP_AUTH_USER'] == $user && $value['PHP_AUTH_PW'] == $pw) {
$flag = true;
**echo "<p>Pozdrav $user, unijeli ste $pw kao zaporku.</p>\n";**
break;
}
if($flag){
header('location: index.php');
} else {
http_response_code(401);
header("WWW-Authenticate: Basic realm=\"SECRET\"");
echo "<p>Try again.</p>\n";
}
}
}
here is my .json file
{
"user":"admin",
"password":"admin"
},
{
"user":"login",
"password":"login"
}
it just throws me a mistake to try again, it doesn't check json file.
Please add a pair of square brackets to enclose your "json data" , which contains an array of data (multiple username and password pairs).
Hence, the following will be one of a ways to get the username and password from the json data (I commented out the file_get_contents part and use a string to store it so that it is more straight forward)
<?php
//$json = file_get_contents("./user-data.json");
$json='[{
"user":"admin",
"password":"admin"
},
{
"user":"login",
"password":"login"
},
{
"user":"stackoverflow",
"password":"goodpassword"
}
]';
$json_data = json_decode($json, true);
foreach ($json_data as $key=>$getdata) {
echo $getdata["user"] . "-" . $getdata["password"];
echo "<hr>";
}
?>
See the result in this sandbox (click execute please):
https://wtools.io/php-sandbox/b7Qv
Hence, please amend the above code to perform comparison with $_SERVER["PHP_AUTH_USER"] and $_SERVER["PHP_AUTH_PW"] to suit your case.
So, change the block:
$user = $_SERVER["PHP_AUTH_USER"];
$pw = $_SERVER["PHP_AUTH_PW"];
$flag =false;
foreach ($json_data as $key => $value) {
if ($value['PHP_AUTH_USER'] == $user && $value['PHP_AUTH_PW'] == $pw) {
$flag = true;
**echo "<p>Pozdrav $user, unijeli ste $pw kao zaporku.</p>\n";**
break;
}
to
$user = $_SERVER["PHP_AUTH_USER"];
$pw = $_SERVER["PHP_AUTH_PW"];
$flag =false;
foreach ($json_data as $key=>$getdata) {
if ($user == $getdata["user"] && $pw == $getdata["password"]) {
$flag = true;
**echo "<p>Pozdrav $user, unijeli ste $pw kao zaporku.</p>\n";**
break;
}
}

Php txt database reading

I'm working on a flat-file based login session. I'm modifying it to require only MD5 password. This is the txt file containing users and passwords MD5.
admin:5f4dcc3b5aa765d61d8327deb882cf99
user1:7c6a180b36896a0a8c02787eeafb0e4c
user2:6cb75f652a9b52798eb6cf2201057c73
And this is a part of my php code.
/* Bool validateLogin() returns TRUE if login/password are valid. Returns FALSE and sets $this->errorMessage if invalid or other error. */
function validateLogin() {
$this->errorMessage = '';
$this->processLoginInput();
if($this->parseUserFile()) {
if( md5($_POST['password']) == $this->userData['password']) {
$_SESSION['loginId'] = $_POST['password'];
return(TRUE); }
else { $this->errorMessage = "Invalid user name and/or password"; }
}
else { $this->errorMessage = "Unable to read user login data file"; }
return(FALSE);
} // end validateLogin()
/* Mixed parseUserFile(). Returns number of users in userFile, else FALSE */
function parseUserFile() {
$this->userData = array();
if(is_readable($this->userFile)) {
$lines = file($this->userFile);
foreach($lines as $line) {
$line = trim($line);
if($line == "") { continue; }
$parts = preg_split('/:/', trim($line));
if(count($parts) >= 2) {
list($user, $password) = $parts;
$this->userData['password'] = $password; } } }
return((count($this->userData)) ? count($this->userData) : FALSE );
}// end parseUserFile()
MY PROBLEM: it gives me access ONLY with the last password in the list txt.
The first and second passwords won't work.
Can you spot any mistake in the code guys?
I don't know PHP much but the issue appears to me from your code is in parseUserFile and is that you are looping through the file contents and in each iteration you are assigning.
$this->userData['password'] = $password; }
So, in each iteration, userData array's same item (i.e. item with key 'password') is getting overwritten by the password value in that line. So, after it finishes with looping through all the items in the file, it holds only the value of last password.
Instead what you should be doing is this:
//Pass in user name to fetch password for the user
function parseUserFile($userName) {
$this->userData = array();
if(is_readable($this->userFile)) {
$lines = file($this->userFile);
foreach($lines as $line) {
$line = trim($line);
if($line == "") { continue; }
$parts = preg_split('/:/', trim($line));
if(count($parts) >= 2) {
list($user, $password) = $parts;
//Get password for the user.
if($user == $userName)
$this->userData['password'] = $password; } } }
return((count($this->userData)) ? count($this->userData) : FALSE );
}// end parseUserFile()

How to read a file line by line in php and compare it with an existing string?

I tried to write this program to compare a user-name in a file with an entered user-name to check whether it exists, but the program doesn't seem to work. Please help. The program was supposed to open a file called allusernames to compare the usernames. If the user name was not found, add it to the file.
<?php
$valid=1;
$username = $_POST["username"];
$listofusernames = fopen("allusernames.txt", "r") or die("Unable to open");
while(!feof($listofusernames)) {
$cmp = fgets($listofusernames);
$val = strcmp($cmp , $username);
if($val == 0) {
echo ("Choose another user name, the user name you have entered has already been chosen!");
$valid=0;
fclose($listofusernames);
break;
} else {
continue;
}
}
if($valid != 0) {
$finalusers = fopen("allusernames.txt", "a+");
fwrite($finalusers, $username.PHP_EOL);
fclose($finalusers);
?>
you need to replace linefeed/newline character from each line to compare.
while(!feof($listofusernames)) {
$cmp = fgets($listofusernames);
$cmp = str_replace(array("\r", "\n"), '',$cmp);
$val = strcmp($cmp , $username);
if($val == 0) {
echo ("Choose another user name, the user name you have entered has already been chosen!");
$valid=0;
fclose($listofusernames);
break;
} else {
continue;
}
}
i have added following line in you code
$cmp = str_replace(array("\r", "\n"), '',$cmp);
I havent tested this but I wonder if you could use something like
<?php
$user = $_POST["username"];
$contents = file_get_contents("allusernames.txt");
$usernames = explode("\n",$contents);
if(in_array($user,$usernames))
{
echo "Choose another username";
}
else
{
$contents .= "\n".$user;
file_put_contents("allusernames.txt",$contents);
}
I think things like file get contents etc. need a certain version of PHP but they do make things a lot nicer to work with.
This also assumes that your usernames are seperated by new lines.
Yo can do this more simple with this code:
<?php
$username = $_POST["username"];
$listofusernames = 'allusernames.txt';
$content = file($listofusernames);
if(in_array($username, $content)) {
echo ("Choose another user name, the user name you have entered has already been chosen!");
} else {
$content[] = $username . PHP_EOL;
file_put_contents($listofusernames, implode('', $content));
}
?>

PHP - Echo an array value from a class

I have the following PHP code
<?php
class SimpleEmailServiceMessage
{
public function properNames($formValue) {
$formValue = strtolower($formValue); //Make all letters small case
$formValue = ucwords($formValue); //Make all first letters capital
$formValue = str_replace('','',$formValue); //Remove extra spaces
if(is_numeric($username)) {
$error[] = 'The name is invalid';
}
return $error;
return $formValue;
}
}
$username = 'john doe';
$m = new SimpleEmailServiceMessage();
echo $m->properNames($username);
foreach($error as $result) {
echo $result . '<br>';
}
?>
I am managing to output $username, but I am not managing to output $error[] if it is a number. $error[] in my case is an array as different classes will have an error.
The current code is telling me Array Warning: Invalid argument supplied for foreach() in /web/com/140895582016925/main.php on line 22 which is for foreach($error as $result) {
The error message say it all: your $error is NOT an array.
Take a look at the is_numeric() validation part of your code.
You have an error there.
is_numeric() needs an argument.
In your case i think you need to:
if ( is_numeric($formValue ) )
{
// execute if condition
}
try this
<?php
class SimpleEmailServiceMessage
{
public $error;
public function properNames($formValue) {
$formValue = strtolower($formValue); //Make all letters small case
$formValue = ucwords($formValue); //Make all first letters capital
$formValue = str_replace('','',$formValue); //Remove extra spaces
if(is_numeric($formValue)) {
$this->error[] = 'The name is invalid';
}
return $formValue;
}
}
$username = 'john doe';
$m = new SimpleEmailServiceMessage();
echo $m->properNames($username);
if(isset($m->error))
{
foreach($m->error as $result) {
echo $result . '<br>';
}
}
?>
Demo
Try to use assignment:
$error = $m->properNames($username);
instead of echoing:
echo $m->properNames($username);

PHP Function Stops Executing- no errors

I have been debugging some php code today and have run into a very strange problem. A function that I have to check if a password is valid stops executing part way through the function. No errors are generated either by PHP or by the web server itself.
Here is the function in question:
//Common Registration Functions
function checkPassword($password)
{
$bLen = strlen($password);
echo $bLen."\n";
echo $password."\n";
//Remove any illegal characters
$vPWord = preg_replace("/[^\!\#\#\\\$\%\&\*\-\_\,\.a-zA-Z0-9]/","",$password);
$aLen = strlen($vPWord);
echo $aLen."\n";
echo $vPWord."\n";
//If the password length before santization is different than after then the user used illegal characters
if ($bLen <> $aLen)
{
return "pass_charfail";
}
echo "pass length check 1 \n";
//Check sanitized password length
if (strlen($vPWord) < 6)
{
return "pass_short";
}
echo "pass length check 2 \n";
if (strlen($vPWord) > 10)
{
return "pass_long";
}
echo "pass length check 3 \n";
//Check password strength
$strength = 0;
if (preg_match("/[^a-z]/",$vPWord))
{
$strength += 1;
}
if (preg_match("/[^A-Z]/",$vPWord))
{
$strength += 1;
}
if (preg_match("/[^0-9]/",$vPWord))
{
$strength += 2;
}
if (preg_match("/[^\!\#\#\\\$\%\&\*\-\_\,\.]/",$vPWord))
{
$strength += 4;
}
if ($strength > 6)
{
echo $strength."\n";
return true;
}
else
{
echo $strength."\n";
return "pass_weak";
}
}
Here is the output I get from my error checking setup (my webhost will not enable php debugging for an entire site so I have to go through a separate file which I will post the code from later):
4
Mast
4
Mast
{"success":"noerror"}
Here is the way I have to check for errors:
<?php
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
include("register.php");
?>
And here is the function which calls the function in question above:
function register($username, $password, $email, $squestion, $sanswer)
{
//First check if the email is valid
$data = eVerify($email);
//If email is not valid
if (!$data)
{
return "email_fail";
}
//If email is valid then check if it already exists and the verification status
else
{
//See if the email already exists
$data = getUID($email,"email",true);
//echo $data."\n";
if ($data)
{
//Get user ID for later use
$id = getUID($email,"email",false);
//If the email exists, see if it has been verified or not
$data = checkVer($id);
//echo $data."\n";
//If email exists but has not been verified
if (!$data)
{
rSVCode($username,$email,$id);
return "exists1";
exit();
}
//If email exists and has been verified
else if ($data)
{
return "exists2";
exit();
}
}
//If email does not exist, continue registration process
else
{
//Check to see if username has been used
$data = getUID($username,"username",true);
if ($data)
{
return "un_exists";
exit();
}
//Check password strength, chars, and length
else
{
$data = checkPassword($password);
if ($data)
{
//Create user account
$data = cAccount($username, $password, $email, $squestion, $sanswer);
if ($data)
{
//Get user's ID for use later
$id = getUID($username,"username",false);
//Generate email verification code
$data = cVCode($username,$email,$id);
//Send verification email
$data = sendEVar($email,$username,$data);
if ($data)
{
return "true";
exit();
}
else
{
return $data;
exit();
}
}
else
{
return $data;
exit();
}
}
else
{
return $data;
exit();
}
}
}
}
}
The triple === makes sure the return is of the same type.
In your function you don't always return boolean, sometimes you return strings, and that could be an issue.
For example this snippet:
$data = "pass_charfail";
if($data){
echo 'true';
}else{
echo 'false';
}
this will echo true because $data is not an empty string.
But the following will echo false, because $data is not a true boolean.
$data = "pass_charfail";
if($data === true){
echo 'true';
}else{
echo 'false';
}
One more example in your register function you have
if ($data)
{
return "true";
exit();
}
if this value gets return, then false will be echo from the following code:
if($data === true){
echo 'true';
}else{
echo 'false';
}
because $data is now a string which is not of type boolean.
hope it makes sense to you!
I got it working again but I am not sure why the change I made makes a difference. If someone could respond to this answer or post their own answer explaining it would be appreciated.
How I fixed it was changing the if ($data) line after checkPassword is called to if ($data === true) and it reported the correct error message instead of claiming a successful registration.

Categories