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()
Related
this thing really blown my mind up i want to design a page with a text box where my clients can enter their username and by using php i want to tell the page to check if there is a username such as that in a file named locationn.html if existed create a cookie and let him in another page if not add a new line to the file containing the user name entered.
this is my code in this code "unamec" is the name of the cookie and "$user" is the user name and "umname" is the name of the username text box which its value is sent to the page itself using a post method.
<?php
if(isset($_POST["uname"])){
$user=$_POST["uname"];
$pass=$_POST["passs"];
$see=file_get_contents("locationn.html");
$lines=explode("\n",$see);
foreach($lines as $line){
if($line == $user){
setcookie("unamec",$user,time()+86400,"/");
echo '<script>window.location="main.html";</script>';
}
}
}
?>
I can help you with the storage and retrieval of a username from a file. You could adapt this and couple with session management, to achieve your aims.
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$username = isset($_POST['username']) ? $_POST['username'] : null;
if($username !== preg_replace('/[^a-zA-Z0-9]+/', '', $username))
throw new Exception('Invalid username.');
$userStore = new UserStore('/tmp/creds.txt');
if(! $userStore->isStored($username)) {
if($userStore->storeUsername($username)) {
echo $username . ' stored.';
}
} else {
echo $username . ' is on file.';
}
}
class userStore
{
public $fp;
public $filename;
public function __construct($filename)
{
$this->filename = $filename;
if(!file_exists($this->filename))
file_put_contents($this->filename, null);
$this->fp = fopen($this->filename, "r+");
}
public function isStored($username) {
$username_exists = false;
if(! $size = filesize($this->filename))
return false;
$contents = fread($this->fp, $size);
$lines = array_filter(explode("\n", $contents));
foreach($lines as $line) {
if(trim($line) == $username) {
$username_exists = true;
break;
}
}
return $username_exists;
}
public function storeUsername($username)
{
$fp = $this->fp;
if (flock($fp, LOCK_EX)) {
fwrite($fp, "$username\n");
fflush($fp);
flock($fp, LOCK_UN);
} else {
return false;
}
return true;
}
}
?>
<form method='POST'>
<input type='text' name='username'>
<input type='submit' value='login'>
</form>
I found this amazing code for flatfile login session:
<?php class Login {
// ATTRIBUTES
// User-modifiable:
var $userFile = 'users.txt'; // pathname of user login data file
var $homePage = ""; // // redirect to this URI after logout
// Do not modify below this line....
var $formData = array();
var $userData = array();
// Constructor
function Login() {
// init formData values:
$this->formData['loginId'] = "";
$this->formData['loginPassword'] = "";
$this->formData['loginAccess'] = "";
// start session
session_start();
// handle logout request:
if(!empty($_POST['logout']) or !empty($_GET['logout'])) {
$this->logout(); }
// handle login request:
elseif(isset($_POST['log_in']) and $this->validateLogin()) {
return(TRUE); } // successful login
// see if we're already logged in:
elseif(!empty($_SESSION['loginId'])) {
return(TRUE); } // already logged in
// display the login form instead of the requested page:
$this->loginForm();
exit; }
// end constructor
/* 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(isset($this->userData[$_POST['name']]) and md5($_POST['password']) == $this->userData[$_POST['name']]['password']) {
$_SESSION['loginId'] = $_POST['name'];
$_SESSION['admin'] = $this->userData[$_POST['name']]['admin'];
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('/\s+/', trim($line));
if(count($parts) >= 3) {
list($user, $password, $admin) = $parts;
$this->userData[$user]['password'] = $password;
$this->userData[$user]['admin'] = $admin; } } }
return((count($this->userData)) ? count($this->userData) : FALSE ); }
// end parseUserFile()
/* Bool loginForm(). Outputs login form HTML. Returns TRUE. */
function loginForm() {
echo <<<EOD
<form action="{$_SERVER['PHP_SELF']}" method="post">
EOD;
if(!empty($this->errorMessage)) { echo "<p id='error'>".$this->errorMessage."</p>\n"; }
echo <<<EOD
<input type="text" name="name" id="name" size="16">
<input type="password" name="password" id="password" size="16">
<input type="submit" name="log_in" id="log_in" value="Log In">
</form>
EOD;
return(TRUE); }
// end loginForm()
/* Int processLoginInput(). Cleans up and sanitizes $_POST data. Returns number of elements in $_POST array. */
function processLoginInput() {
foreach($_POST as $key => $value) {
if(isset($this->formData[$key])) {
if(get_magic_quotes_gpc()) {
$value = stripslashes($value); }
$this->formData[$key] = htmlentities(trim($value)); } }
return(count($_POST)); }
// end processLoginInput()
/* Bool logout(). Logs out user. Returns TRUE or redirects and exits. */
function logout() {
$_SESSION = array();
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time()-42000, '/'); }
session_destroy();
if(!empty($this->homePage)) {
header("Location: " . $this->homePage);
exit; }
return(TRUE); }
// end logout()
} // end class Login
// Instantiate it:
$login = new Login(); ?>
This is the users.txt file which contains the user, the password coded in md5 and whether they are admin (1) or not(0). [admin, password] [user1, password1] [user2, password2]
admin 5f4dcc3b5aa765d61d8327deb882cf99 1
user1 7c6a180b36896a0a8c02787eeafb0e4c 0
user2 6cb75f652a9b52798eb6cf2201057c73 0
MY QUESTION: I want to remove the user from the login, I mean, to recquire only the password to login. I tried this:
/* 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']) { //removed if(isset($this->userData[$_POST['name']]) and [$_POST['name']]
$_SESSION['loginId'] = $_POST['password']; //changed 'name' for 'password'
$_SESSION['admin'] = $this->userData['admin']; //removeded [$_POST['name']]
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('/\s+/', trim($line));
if(count($parts) >= 3) {
list($user, $password, $admin) = $parts;
$this->userData['password'] = $password; //removed [$user]
$this->userData[$user]['admin'] = $admin; } } }
return((count($this->userData)) ? count($this->userData) : FALSE ); }
// end parseUserFile()
It works BUT only with the last password in the list, the rest of the passwords dont work. ANY HELP? Where am i mistaken? XXX
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));
}
?>
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);
I need to telnet to cisco switch using php and execute show interface status command and get results. I tried some php classes I found on internet but none of them could connect to device. So I tried to write the script myself, but I have the same problem, I cant connect to device.
The host sends me banner message and then new line with username:.
I send my username with \r\n, wait some time and tries to read data, but it looks to me like host is just ignoring my new line characters. This is response I got (explode('\n') on response):
Array
(
[0] => %
[1] => User Access Verification
[2] => Username: timeout expired!
)
Why didn't I get prompt on password? I tried it with sending telnet headers, and without, no change. Can anyone please help me?
Here is my code
<?
$host = "switchName";
$name = "name";
$pass = "pass";
$port = 23;
$timeOut = 15;
$connected = false;
$skipNullLines = true;
$timeout = 125000;
$header1=chr(0xFF).chr(0xFB).chr(0x1F).chr(0xFF).chr(0xFB).chr(0x20).chr(0xFF).chr(0xFB).chr(0x18).chr(0xFF).chr(0xFB).chr(0x27).chr(0xFF).chr(0xFD).chr(0x01).chr(0xFF).chr(0xFB).chr(0x03).chr(0xFF).chr(0xFD).chr(0x03).chr(0xFF).chr(0xFC).chr(0x23).chr(0xFF).chr(0xFC).chr(0x24).chr(0xFF).chr(0xFA).chr(0x1F).chr(0x00).chr(0x50).chr(0x00).chr(0x18).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x20).chr(0x00).chr(0x33).chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0x2C).chr(0x33).chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x27).chr(0x00).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x18).chr(0x00).chr(0x41).chr(0x4E).chr(0x53).chr(0x49).chr(0xFF).chr(0xF0);
$header2=chr(0xFF).chr(0xFC).chr(0x01).chr(0xFF).chr(0xFC).chr(0x22).chr(0xFF).chr(0xFE).chr(0x05).chr(0xFF).chr(0xFC).chr(0x21);
function read_string()
{
global $fw,$host,$skipNullLines;
$string = "";
while( !feof($fw) )
{
$read = fgets($fw);
$string .= $read;
// Probably prompt, stop reading
if( strpos($read, ':') !== FALSE || strpos($read, '> (enable)') !== FALSE || strpos($read, $host.'#') !== FALSE)
{ break; }
}
$string = explode("\n", $string);
// Get rid of null lines
$ret = array();
for($i = 0; $i<count($string); $i++)
{
if( trim($string[$i]) == '' && $skipNullLines ) continue;
$ret[] = $string[$i];
}
return $ret;
}
function send_string($string, $force=false)
{
GLOBAL $timeout,$fw;
$string = trim($string);
// execute only strings that are preceded by "show" (if not forced)
if(!$force && strpos($string, 'show ') !== 0)
{
return 1;
}
fputs($fw, $string."\r\n");
echo("SEND:".$string."\r\n");
usleep($timeout);
}
$fw = fsockopen($host, $port, $errno, $errorstr, $timeOut);
if($fw == false)
{
echo("Cant connect");
}
else
{
echo("Connected<br>");
$connected = true;
stream_set_timeout($fw, $timeout);
// fputs($fw, $header1);
// usleep($timeout);
// fputs($fw, $header2);
// usleep($timeout);
print_r(read_string());
send_string("test", true);
print_r(read_string());
}
fclose($fw);
?>
UPDATE
If I send username at first, and then I read, I get password prompt. I dont understand it, why cant I firstly read messages from host and then send my response. The way it works to me now (send response and then read for prompt) is no-sense! (and I still got "% Authentication failed." message event with right password/name).
...
$connected = true;
stream_set_timeout($fw, $timeout);
send_string("name", true);
send_string("password", true);
print_r(read_string());
...
Okay, so I dont know what was the problem, but after "few" tests I was able to write this class that works for me. I dont know why other telnet classes dont work altough they do pretty much the same. So if anyone will have similar problem, you can try this:
class TELNET
{
private $host;
private $name;
private $pass;
private $port;
private $connected;
private $connect_timeout;
private $stream_timetout;
private $socket;
public function TELNET()
{
$this->port = 23;
$this->connected = false; // connected?
$this->connect_timeout = 10; // timeout while asking for connection
$this->stream_timeout = 380000; // timeout between I/O operations
}
public function __destruct()
{
if($this->connected) { fclose($this->socket); }
}
// Connects to host
// #$_host - addres (or hostname) of host
// #$_user - name of user to log in as
// $#_pass - password of user
//
// Return: TRUE on success, other way function will return error string got by fsockopen()
public function Connect($_host, $_user, $_pass)
{
// If connected successfully
if( ($this->socket = #fsockopen($_host, $this->port, $errno, $errorstr, $this->connect_timeout)) !== FALSE )
{
$this->host = $_host;
$this->user = $_user;
$this->pass = $_pass;
$this->connected = true;
stream_set_timeout($this->socket, 0, 380000);
stream_set_blocking($this->socket, 1);
return true;
}
// else if coulnt connect
else return $errorstr;
}
// LogIn to host
//
// RETURN: will return true on success, other way returns false
public function LogIn()
{
if(!$this->connected) return false;
// Send name and password
$this->SendString($this->user, true);
$this->SendString($this->pass, true);
// read answer
$data = $this->ReadTo(array('#'));
// did we get the prompt from host?
if( strtolower(trim($data[count($data)-1])) == strtolower($this->host).'#' ) return true;
else return false;
}
// Function will execute command on host and returns output
//
// #$_command - command to be executed, only commands beginning with "show " can be executed, you can change this by adding
// "true" (bool type) as the second argument for function SendString($command) inside this function (3rd line)
//
function GetOutputOf($_command)
{
if(!$this->connected) return false;
$this->SendString($_command);
$output = array();
$work = true;
//
// Read whole output
//
// read_to( array( STRINGS ) ), STRINGS are meant as possible endings of outputs
while( $work && $data = $this->ReadTo( array("--More--","#") ) )
{
// CHeck wheter we actually did read any data
$null_data = true;
foreach($data as $line)
{
if(trim($line) != "") {$null_data = false;break;}
}
if($null_data) { break;}
// if device is paging output, send space to get rest
if( trim($data[count($data)-1]) == '--More--')
{
// delete line with prompt (or "--More--")
unset($data[count($data)-1]);
// if second line is blank, delete it
if( trim($data[1]) == '' ) unset($data[1]);
// If first line contains send command, delete it
if( strpos($data[0], $_command)!==FALSE ) unset($data[0]);
// send space
fputs($this->socket, " ");
}
// ak ma vystup max dva riadky
// alebo sme uz nacitali prompt
// IF we got prompt (line ending with #)
// OR string that we've read has only one line
// THEN we reached end of data and stop reading
if( strpos($data[count($data)-1], '#')!==FALSE /* || (count($data) == 1 && $data[0] == "")*/ )
{
// delete line with prompt
unset($data[count($data)-1]);
// if second line is blank, delete it
if( trim($data[1]) == '' ) unset($data[1]);
// If first line contains send command, delete it
if( strpos($data[0], $_command)!==FALSE ) unset($data[0]);
// stop while cyclus
$work = false;
}
// get rid of empty lines at the end
for($i = count($data)-1; $i>0; $i--)
{
if(trim($data[$i]) == "") unset($data[$i]);
else break;
}
// add new data to $output
foreach($data as $v)
{ $output[] = $v; }
}
// return output
return $output;
}
// Read from host until occurence of any index from $array_of_stops
// #array_of_stops - array that contains strings of texts that may be at the end of output
// RETURNS: output of command as array of lines
function ReadTo($array_of_stops)
{
$ret = array();
$max_empty_lines = 3;
$count_empty_lines = 0;
while( !feof($this->socket) )
{
$read = fgets($this->socket);
$ret[] = $read;
//
// Stop reading after (int)"$max_empty_lines" empty lines
//
if(trim($read) == "")
{
if($count_empty_lines++ > $max_empty_lines) break;
}
else $count_empty_lines = 0;
//
// Does last line of readed data contain any of "Stop" strings ??
$found = false;
foreach($array_of_stops AS $stop)
{
if( strpos($read, $stop) !== FALSE ) { $found = true; break; }
}
// If so, stop reading
if($found) break;
}
return $ret;
}
// Send string to host
// If force is set to false (default), function sends to host only strings that begins with "show "
//
// #$string - command to be executed
// #$force - force command? Execute if not preceeded by "show " ?
// #$newLine - append character of new line at the end of command?
function SendString($string, $force=false, $newLine=true)
{
$t1 = microtime(true);
$string = trim($string);
// execute only strings that are preceded by "show"
// and execute only one command (no new line characters) !
if(!$force && strpos($string, 'show ') !== 0 && count(explode("\n", $string)) == 1)
{
return 1;
}
if($newLine) $string .= "\n";
fputs($this->socket, $string);
$t2 = microtime(true);
}
}
// EXAMPLE
$host = "hostname";
$name = "username";
$pass = "password";
$t = new TELNET();
echo("CONNECT:".$t->Connect($host, $name, $pass)."<br>");
echo("LOGIN:".(int)$t->LogIn());
echo("<br>OUTPUT:<br>");
print_r($t->GetOutputOf("show snmp"));
print_r($t->GetOutputOf("show users"));
print_r($t->GetOutputOf("show interface status"));
PS: my devices prompt is "hostname#", so you may need to edit Login function to make this code work with prompt of your device (so you may need in GetOutputOf() )