Posted by: Mat | February 16, 2008

PHP – Week 6

As we’ve seen, we know that in order to impose HTACCESS-based authentication, we need to somehow encrypt our data in order to make it at least a little bit difficult for hackers to read our sensitive data.  Likewise, if we were imposing session-level security, we might consider encrypting our data inside the database. There are three basic types of encryption in use today – uni-directional, bi-directional and PKI-based.  Uni-directional is an encryption method that encrypts data only in one direction; that is, it cannot be specifically decrypted in real-time.  In a uni-directional method, we simply match encrypted data to encrypted data because the rule of encryption is that it must be the same each and every time. PHP provides a built-in function to do this:                 crypt( string [, salt] ) Here, the string is simply the data to be encrypted.  Crypt() uses a standard DES-based algorithm.  The optional – salt – is simply a method to base it on and is in the form of a two-character string.  If a salt is not supplied, PHP chooses a randomly generated salt.  Crypt() is most frequently used with HTACCESS/HTPASSWD systems to encrypt the password string.  Crypt(), however, is not a strong-encryption so it’s use should be limited. A bi-directional encryption method is one in which the encrypted string can be decrypted.  In most cases, bi-directional methods provide for a number of algorithmic encrypt-decrypt schemes, called ciphers, to perform the encryption (more below). Amongst the more widely used function sets in PHP for bi-directional encryption is a function set called MCRYPT.  MCRYPT has 35 functions in the set that perform a variety of tasks.  However, we will not spend an inordinate amount of time covering these tasks as it is increasingly complex.  If you would like more information on the MCRYPT set, go to http://www.php.net/manual/en/ref.mcrypt.php. Ciphers are basic encryption algorithms – that is, mathematical functions that perform the encryption scheme.  There are many of them to choose from, and usually most of them have varied options to increase the level of security by using a stronger key.  Of the ones natively supported by PHP (note that some are not free to use, though most are): 

MCRYPT_3DES
MCRYPT_ARCFOUR_IV MCRYPT_ARCFOUR MCRYPT_BLOWFISH
MCRYPT_CAST_128
MCRYPT_CAST_256
MCRYPT_CRYPT
MCRYPT_DES
MCRYPT_DES_COMPAT MCRYPT_ENIGMA
MCRYPT_GOST
MCRYPT_IDEA
MCRYPT_LOKI97
MCRYPT_MARS
MCRYPT_PANAMA MCRYPT_RIJNDAEL_128 MCRYPT_RIJNDAEL_192 MCRYPT_RIJNDAEL_256
MCRYPT_RC2
MCRYPT_RC4
MCRYPT_RC6
MCRYPT_RC6_128
MCRYPT_RC6_192
MCRYPT_RC6_256
MCRYPT_SAFER64
MCRYPT_SAFER128
MCRYPT_SAFERPLUS
MCRYPT_SERPENT MCRYPT_SERPENT_128 MCRYPT_SERPENT_192 MCRYPT_SERPENT_256 MCRYPT_SKIPJACK
MCRYPT_TEAN
MCRYPT_THREEWAY
MCRYPT_TRIPLEDES
MCRYPT_TWOFISH
MCRYPT_TWOFISH128
MCRYPT_TWOFISH192
MCRYPT_TWOFISH256
MCRYPT_WAKE
MCRYPT_XTEA

Personal choice – I use MCRYPT_RIJNDAEL_256 largely because it is a strong encryption method and it sets encypted data in Base64 which is ostensibly an all-text string.  This allows me to pass encrypted data in and out of a database and PHP without having to perform string manipulation or escaping (many others use any character, including both escapable characters and the \ escape key) in the encrypted output. The most popular algorithm in use is 3DES (or TripleDES) which is a process of encrypting an encrypted string of an encryption using the DES algorithm three times in a row.  However, this algorithm frequently takes a lot of processing power in comparison to others.  Because of its intricacies, we will not be going into an extended discussion of PKI (Public Key Infrastructure).  File Handling  PHP, like most dynamic scripting languages, has a unique ability to interact with files on the server.  We’ve already seen that we can include and run externally located script files using the include() and require() functions. PHP has an extensive library of built-in functions that allow you to create, open, read, write to, and delete files (as well as interact with them on a non-include processing level).  This is particularly important in the HTACCESS scenario because the password file itself is really just an ASCII-based text file.  In most cases, such as the HTACCESS example, we can assume that the file already exists.  For simple demonstrative purposes, let’s always assume that the file we want to access is already in the same folder as the script.  Let’s assume the file looks like this: textfile.txt

This is a simple text file.
There are five lines in this file.
Each line has a different sentence.
The all have newline (carriage returns) after each line.
This is the end of the text file.

This is the methods you can use to access, read and display the file contents: textreader.php

<?php 
// assign the file to a variable
$filename = “textfile.txt”; // open the file, assigning the process to a variable
// note the “r” at the end of the fopen function
$handle = fopen($filename, “r”); 
// ‘read’ the textfile into a variable using the
// fread function
//
note the second argument in fread – filesize()
// which is itself
a function that tells the fread
// function the total number of
bytes to read
$contents = fread($handle,filesize($filename)); // close the open handle
fclose($handle); 
// display the contents
echo $contents; ?>

Given the above, what will the user see? In addition to reading the file contents as a single string variable, you can also read it directly into an array!  Hint – this is exactly what an HTPASSWD file is.  Second hint – this is really nothing more than an array! text_to_array.php

<?php 
$filename = “textfile.txt”;
$handle = fopen($filename, “r”); // ‘read’ the textfile into an array using the file
// function instead 
of the fread function.  Note that
// you do NOT need to declare the filesize. Also note
// that this procedure assumes that each new 
line is a
// separated value in the array.  Finally, note that we
// declare the filename inside the file function, not
// the handler.
$contents = file($filename); // close the open handle
fclose($handle);  // display the contents
for ( $i = 0; $i < sizeof($contents); $i++ ) {  
 
echo $contents[$i].”<hr />”;
} ?>

Given the above, what will the user see? We can also write to a file.  There are two types of writing – creation (full write) and appending (concatenation). filewriter.php

<?php 
$filename = “textfile.txt”;
$newcontent = “This is a line I am adding to the file.”;
$handle = fopen($filename, “a”); // append a line to the end of the text file.  Note that
// here I am 
doing two things – I am checking if I can
// even write to the file 
and if not to display an error
// message and exit, otherwise to go 
ahead and write and
// save it.
if ( fwrite($handle,$newcontent) === FALSE ) {  
  echo “Cannot write to file “.$filename;
  
 
exit;
} echo “Line ‘”.$newcontent.”‘ was added to ”.$filename; // close the open handle
fclose($handle); 
?>

At this point you’ll notice that the fopen() function has several second arguments (called the mode)_that can be used in file operations.  The complete list is: 

Mode Description
r Open for read only, places pointer at beginning of file
r+ Open for reading and writing, places pointer at beginning of file
w Open for writing only, places pointer at beginning of file and truncate file to zero length.  If file does not exist attempt to create it.
w+ Open for reading and writing, places pointer at beginning of file and truncate file to zero length.  If file does not exist attempt to create it.
a Open for writing only; place the file pointer at the end of the file. If the file does not exist, attempt to create it.
a+ Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it.
x Create and open for writing only; place the file pointer at the beginning of the file. If the file already exists, the fopen() call will fail by returning FALSE and generating an error of level E_WARNING. If the file does not exist, attempt to create it. This is equivalent to specifying O_EXCL|O_CREAT flags for the underlying open(2) system call. This option is supported in PHP 4.3.2 and later, and only works for local files.
x+ Create and open for reading and writing; place the file pointer at the beginning of the file. If the file already exists, the fopen() call will fail by returning FALSE and generating an error of level E_WARNING. If the file does not exist, attempt to create it. This is equivalent to specifying O_EXCL|O_CREAT flags for the underlying open(2) system call. This option is supported in PHP 4.3.2 and later, and only works for local files.

Note that there is a special switch mode using the ‘b’ in combination with the primary mode.  Using the b allows you to work with binary files, and also has special significance for Windows based PHP servers.  The php.net web site has particularly good resources for file operations.  File Operation Handlers/Security One thing we might want to do is check and make sure our file even exists first before we determine what operation to do.  We also might need to check if the security level permits us to write to a file if we need to do these types of operations. filechecker.php

<?php 
// declare the file by assigning it to a variable
$filename = “textfile.txt”;  // check if the file exists before continuing
if ( file_exists($filename) ) {  
 
// check if you can write to the file
  
 
if ( is_writable($filename) ) {
     
   
// continue with fwrite operations
  
 
} else {
     
   
echo “Sorry, you cannot write to the file”;
  
 
}
} else {  
 
// file does not exist
  
 
echo “Sorry, the file “.$filename.” does not exists! “;
} ?>

Mail PHP has a very nifty feature that allows you to create and send an email message very quickly and easily.  The function mail() is based on the UNIX command sendmail which sends a message to any POP email account via SMTP but without a directly declared host.  

<?php 
// declare the mail headers
$headers = ‘From: mat@mobimeet.com’.”\r\n”
  .
‘Reply-To: mat@mobimeet.com’.”\r\n”
  .
‘X-Mailer: PHP/’.phpversion(); // compose the body
$to = ‘nobody@example.com’;
$subject = ‘the subject’;
$message = ‘hello’; // send the mail
mail($to, $subject, $message, $headers); ?>

Note the use of the function phpversion() which has no arguments.  For more information, look into php.net. For a more extended example, see the download package from this week’s notes. In addition to mail(), PHP does have full-featured SMTP and POP, as well as LDAP capabilities.  However, we will not cover these aspects due to time constraints.  Creating Your Own Functions One of the greatest achievements and differentiators between dynamic scripting languages (including client-side scripting languages) and non-dynamic languages (markups, such as HTML) is the ability to create your own functions. We already know that PHP by and large operates by using any number of built-in functions.  But of course, Zend could not possibly conceive of every potential function in the world.  As we’ve already discussed, a function is simply a self-contained mini-program that based on inputs derives and output or performs a task. In most programming, we frequently do some things over and over.  And many times, there is some thread of commonality between these events.  By creating your own functions, you can both avoid the repetition of typing the operation recursively and at the same time make the performance consistent. For example, UNIX-based PHP has a built-in function money_format() that changes a numeric into a currency string: 

$x = 3;
echo money_format($x,2);  
// returns $3.00

However, this function does not exist in Windows-based servers.  To perform this operation we might consider programming our own version. 

function make_curr_fmt($num=0,$dec=2,$sym=$) {  
  return $sym.number_format($num, $dec);
}

One caveat … you cannot name a function the same as any existing built-in function and you can only use the name once (in other words, you cannot create two functions called make_currency_format() in your scripts).  Note in this example that there are several things happening: 

  1. I declare my function by using the statement declaration function
  2. I name my function (in this case make_currency_symbol)
  3. I declare my inbound variables with defaults (the defaults are optional but if I fail to declare a default and I call the function without it, it will error out – in the example, if I made the call make_currency_symbol() the return would be $0.00
  4. I declare the statement return which sends the output back into the processor.  If I do not declare the return, it will simply exit without any value, though it might have performed any operations contained in it
  5. I declare the end of the statement with the close } Functions are particularly useful when an operation I am performing has a series of built-in functions that make it difficult to decipher the code Frequently programmers will put all of the functions they create onto a single script page and include it on all output script pages, which provides for consistent operations and handling across the board. 

 Week 6 Notes for IMD402


Leave a response

You must be logged in to post a comment.

Categories