Month: June 2012

PHP Debugging: Displaying Error Message in HTML output

When debugging PHP code, it can be useful to display PHP errors within the output. Normally, PHP error messages are written to the Apache log.

To have PHP errors in your browser output, you can use this command in your PHP script

ini_set(‘display_errors’, 1);

Below is a short example PHP script that demonstrates.

<?php
print “The following include fails quietly.<br/>n”;
include(“first_missing.inc”);
print “After first failed include.<br/>n”;
print “——<br/>n”;
print  “Now we switch on display_errors.<br/>n”;
ini_set(‘display_errors’, 1);
print “——<br/>n”;
print “Now, the second include fails with following error messages.<br/>n”;
print “<br/><i>n”;
include(“second_missing.inc”);
print “</i><br/><br/><br/>n”;
print “After second failed include.<br/>n”;
?>

And here is the output from the script.

The following include fails quietly.
After first failed include.
——
Now we switch on display_errors.
——
Now, the second include fails with following error messages.

Warning: include(): Unable to access second_missing.inc in /export/www/sites/testsite/error3.php on line 19  Warning: include(second_missing.inc): failed to open stream: No such file or directory in /export/www/sites/testsite/error3.php on line 19 Warning: include(): Failed opening ‘second_missing.inc’ for inclusion (include_path=’.:/usr/share/php:/usr/share/pear’) in /export/www/sites/testsite/error3.php on line 19

After second failed include.

JumpForward SSO Bridge

The following is example PHP code for use by academic institutions attempting to bridge their current single sign on authentication system with JumpForward.  This code is meant for example purposes only, and is no way meant to reflect finished code.

<?php
  //Author: Dylan F. Marquis
  //Email: dylan(dot)marquis(at)uconn(dot)edu
  //June 2012

  //API Key stored in a variable named $apiKey within the included file
  include '.apikey.php';

  //Filtered input container
  $clean = array();

  //Pull User ID from SSO -> This may differ based on authentication service
  $ssoId = $_SERVER['REMOTE_USER'];

  //Send a SOAP request to API -> Assign response to a variable and pull hash value by property
  try {$client = new SoapClient("https://api.jumpforward.com/services.asmx?WSDL");}
  catch (Exception $e)
  {
       header( 'Location: https://redirect_to_error_page.php' );
       trigger_error('Connection to the JumpForward API failed',E_ERROR);
  }
  $result = $client->GetStudentAthleteLoginHash(array('APIKey' => $apiKey, 'StudentId' => $ssoId));
  $hash = $result->GetStudentAthleteLoginHashResult;

  //Redirect unauthorized users (302)
  if ($hash=="Student Not Found")
  {
       header( 'Location: https:https://redirect_to_error_page.php' );
       trigger_error('StudentID not found by JumpForward Server',E_ERROR);
  }
  else
  {
       //Clean data sent from JumpForward
       if (preg_match('"^[a-zA-Z0-9_!.:/+-=]+(?!><$)$"', $hash))
       {
            $clean['hash'] = $hash;
       }
  else
  {
       header( 'Location: https://https://redirect_to_error_page.php' );
       trigger_error('Invalid data was received from JumpForward API',E_ERROR);
 }
       //POST hash to JumpForward SSO
       echo '<html><head></head><body><form action="https://college.jumpforward.com/sso.aspx" id="hash_form" method="post"><input type="hidden" id="hash" name="hash" value="'.$clean['hash'].'" /><script language="JavaScript" type="text/javascript">document.getElementById("hash_form").submit();</script></form></body></html>';
  }
?>

The filtered input container array $clean bears some explanation. This is not a functional part of the code, it is merely a means to identifying filtered data. This procedure was developed by Chris Shiflett as a way to prevent XSS.

$clean = array();

Additionally, the regular expression being run to filter the hash response from JumpForward, is also unnecessary to the proper functionality of this code. This has been added as a safeguard in the event that the JumpForward server is compromised and sends tainted data back as a response.  The regular expression is set to exclude any character that are not part of the Base64 character set.

if (preg_match('"^[a-zA-Z0-9_!.:/+-=]+(?!><$)$"', $hash))
{
     $clean['hash'] = $hash;
}
Posted in PHP

Starting Google Apps and GAM (Google Apps Manager)

GAM is a command-line tool for manipulating Google Apps accounts. It is written in Python, and uses Google’s gdata Python module.

GAM is documented at http://code.google.com/p/google-apps-manager/. The gdata Python module is documented at http://code.google.com/p/gdata-python-client/.

Installing GAM
When you install GAM, it installs the gam.py Python script, and the gdata module in its own directory. See instructions on the GAM page linked above.

Configuring GAM
To use GAM, you need to configured it to use your Google Apps Management credentials. This involves running this on the command-line;

python gam.py info domain

This will guide you through the process, during which your web browser will open to a page on Google Apps where you can verify certain information. The link to GAM above explains the details. Once you have authenticated, a credentials file called oauth.txt is created in the current directory. Future invocations of python gam.py will automatically load and use the credentials in oauth.txt.

Using GAM
Once you have configured gam.py to automatically authenticate when run, you can run gam.py with a number of parameters. For example, to get information on the user joe.user, you could do this

python gam.py info user joe.user@uconn.edu

and see something like this

User: joe.user
First Name: Joe
Last Name: User
Is an admin: false
Has agreed to terms: true
IP Whitelisted: false
Account Suspended: false
Must Change Password: false
Email Aliases (Nicknames):
Groups:

Starting Google Apps and GAM (Google Apps Manager)

GAM is a command-line tool for manipulating Google Apps accounts. It is written in Python, and uses Google’s gdata Python module.

GAM is documented at http://code.google.com/p/google-apps-manager/. The gdata Python module is documented at http://code.google.com/p/gdata-python-client/.

Installing GAM
When you install GAM, it installs the gam.py Python script, and the gdata module in its own directory. See instructions on the GAM page linked above.

Configuring GAM
To use GAM, you need to configured it to use your Google Apps Management credentials. This involves running this on the command-line;

python gam.py info domain

This will guide you through the process, during which your web browser will open to a page on Google Apps where you can verify certain information. The link to GAM above explains the details. Once you have authenticated, a credentials file called oauth.txt is created in the current directory. Future invocations of python gam.py will automatically load and use the credentials in oauth.txt.

Using GAM
Once you have configured gam.py to automatically authenticate when run, you can run gam.py with a number of parameters. For example, to get information on the user joe.user, you could do this

python gam.py info user joe.user@uconn.edu

and see something like this

User: joe.user
First Name: Joe
Last Name: User
Is an admin: false
Has agreed to terms: true
IP Whitelisted: false
Account Suspended: false
Must Change Password: false
Email Aliases (Nicknames):
Groups:

Adopt the cloud, kill your IT career

http://www.infoworld.com/print/195144

…You might be eager to relinquish responsibility of a cranky infrastructure component and push the headaches to a cloud vendor, but in reality you aren’t doing that at all. Instead, you’re adding another avenue for the blame to follow. The end result of a catastrophic failure or data loss event is exactly the same whether you own the service or contract it out. The difference is you can’t do anything about it directly. You jump out of the plane and hope that whoever packed your parachute knew what he or she was doing….

Using the UITS SSH Gateway

Adding the following to your ~/.ssh/config will cause all SSH access to servers named *.uits.uconn.edu to hop through ssh.uits.uconn.edu, authenticating as your NetID.  Note that if you have kinit’d as <NETID>/admin, or if you have copied your public SSH key to ssh.uits.uconn.edu and are using ssh-agent, this will be transparent.

Host ssh.uits.uconn.edu
    ProxyCommand none

Host *.uits.uconn.edu
    ProxyCommand ssh -A <NETID>@ssh.uits.uconn.edu exec nc %h %p

MySQLi

MySQLi (MySQL Improved) has many advantages over the older PHP MySQL driver.  It takes advantage the newer features built into MySQL 4.1.3 and newer.  Below are some simple examples of basic MySQL functions (SELECT, INSERT, UPDATE and DELETE).

SELECT

$mysqli = new mysqli('$server', '$user', '$pass', '$db');
if (mysqli_connect_errno())
        {
        printf ("Connect failed: %sn", mysqli_connect_error());
        exit();
        }

$query = 'SELECT first_name, last_name FROM table WHERE id=?';

if ($stmt = $mysqli->prepare($query))
        {
        $stmt->bind_param('s', $param);
        $stmt->execute();
        $stmt->bind_result($first_name, $last_name);
        while($stmt->fetch())
        {
        	echo 'Your name is' . $first_name . $last_name;
        }
        $stmt->close();
        }
$mysqli->close();

//id=? in query statement denotes that the ? will be defined in bind_param
//'s' in bind_param is the data type
		#i - interger
		#d - double
		#s - string
		#b - blob (will be sent in packets)

UPDATE

$mysqli = new mysqli('$server', '$user', '$pass', '$db');
if (mysqli_connect_errno())
        {
        printf ("Connect failed: %sn", mysqli_connect_error());
        exit();
        }
$query = 'UPDATE dfunct_dynamic SET title=?, description=?, code=? WHERE id=?';
if ($stmt = $mysqli->prepare($query))
        {
        $stmt->bind_param("sssi", $title, $description, $code, $id);
        $stmt->execute();
        $stmt->close();
        }
$mysqli->close();

INSERT

$mysqli = new mysqli('$server', '$user', '$pass', '$db');
if (mysqli_connect_errno())
        {
        printf ("Connect failed: %sn", mysqli_connect_error());
        exit();
        }
$query = 'INSERT INTO table (first_name, last_name, title) VALUES (?, ?, ?)';
if ($stmt = $mysqli->prepare($query))
        {
        $stmt->bind_param("ssss", $first_name, $ last_name, $title);
        $stmt->execute();
        $stmt->close();
        }
$mysqli->close();

DELETE

$mysqli = new mysqli('$server', '$user', '$pass', '$db');
if (mysqli_connect_errno())
        {
        printf ("Connect failed: %sn", mysqli_connect_error());
        exit();
        }
$query = 'DELETE from dfunct_dynamic WHERE id=?';
if ($stmt = $mysqli->prepare($query))
        {
        $stmt->bind_param("i", $id);
        $stmt->execute();
        $stmt->close();
        }
$mysqli->close();