Archive

Archive for the ‘Tutorial’ Category

Simulating Slow Connections in OS X or Linux

April 10th, 2013 Comments off

Simulating Slow and Laggy Connections

 

Do you want to simulate how it feels to load your site from a mobile connection (If it’s AT&T just turn off your network for an accurate simulation- I kid, don’t sue. But seriously AT&T, figure it out.) or from a laggy network? In OS X or Linux, you’ve got everything you need already installed: ipfw (IP firewall and traffic shaper control).

Create a Pipe

Configure a pipe with the appropriate bandwidth (I’ve also added a 200 ms response delay in this example).

sudo ipfw pipe 1 config bw 16bit/s delay 200ms

Attach the Pipe

In this example we’re going to use port 80, but you can also use port 443 or any other port that you may be testing communication on. Additionally, you can attach the pipe to multiple ports.

sudo ipfw add 1 pipe 1 src-port 80
sudo ipfw add 2 pipe 1 dst-port 80

That’s it!

Wait a second, you say! Now your network connection is completely throttled and everything is running terribly! You need to delete both ipfw entries and the pipe that were previously created.

Here’s how you undo what you’ve just done:

sudo ipfw delete 1
sudo ipfw delete 2
sudo ipfw pipe 1 delete
Categories: Linux, Tutorial Tags: , , , ,

Subversion: Merging a Branch to Trunk

April 1st, 2013 Comments off

Merging a Subversion Branch Back to Trunk

So, you’ve successfully branched code and have a great new feature set you need to get back to trunk, but how? Easy!

Get the latest revision number of the branch you want to merge

If you already have the branch checked out, cd to that directory and svn update it.

 svn update 
svn log --stop-on-copy 

Alternatively, if you don’t have (or don’t want to have) the branch checked out locally, you can do it remotely.

svn log --stop-on-copy https://url/to/branch

The last line returned contains the first revision of that branch, it’ll look something like this:

$ svn log --stop-on-copy 

... more lines like the one below ...

Subversion commit message. 
------------------------------------------------------------------------ 
rXXXX | mustafaashurex | 2013-04-01 09:50:03 -0700 (Mon, 01 Apr 2013) | 1 line 

Check out trunk

svn co https://url/to/trunk

Alternatively, you can just update trunk if you have it checked out

Change to the trunk working directory and do the following:

svn update

You should see output like this:

$ svn update 
At revision YYYY.

This will update your copy of trunk to the most recent version and tell you the revision you are at. Make note of that number as well (should say “At revision YYYY”; where YYYY is the second number you’ll need to remember).

Perform the merge

Now you’ve got the details you need; the revision at which the branch started and the most current revision.

Change directory to the trunk

svn merge -rXXXX:YYYY https://url/to/branch

Check in the results:

svn ci -m "[MERGE XXXX:YYYY] Merging mySvnProject [branchname] -r[XXXX]:[YYYY] back to trunk."

Final thoughts

Described above is how to perform the act of merging a branch back to the trunk, there are however many things I didn’t cover. Before you perform this operation you should do a review of all the changes and potential conflicts if the trunk was also receiving active development.

In a team environment, this would be a great time for a peer/mentor code review as well as an approach review for the bugs/featured covered in the branch.

Encrypting a tar or gz (gzip) File with OpenSSL

July 17th, 2012 3 comments

When you have sensitive data that you need to transmit but want to make it easy to encrypt and decrypt it, use some standard tools to get the job done!

I recently had an issue where a client was using OS X laptops running an Admin panel written in PHP on MAMP in an environment that may or may not have an internet connection. The problem was that they needed to be able to dump their database data into an encrypted file so that they could send the data off when they get a connection (via email, upload, who knows). My initial response was to use gpg to encrypt the file and hand out the keys to the people who would eventually be reading the data.

Turns out, this was going to be a nightmare and I needed something ‘easier’. How about encrypting a tar file with OpenSSL? Bingo! This solution uses utilities that are already on the machine and no installations need to be performed. The reason this was such a big deal is because the laptops running this software will be all over the world with various levels of technical acumen and it will be a nightmare to make sure every single laptop has been updated correctly.

Encrypting Your File

tar and gzip the file, then encrypt it using des3 and a secret key.

tar cvzf - mysql_dump.sql | openssl des3 -salt -k #YOUR PASSWORD# | dd of=encrypted_mysql_dump

That simple!

Decrypting Your File

dd if=encrypted_mysql_dump |openssl des3 -d -k #YOUR PASSWORD# |tar xvzf -

Essentially, just call all the commands in the reverse order.

Download the Utility Scripts

Download them!

Creating an SSH Proxy Tunnel with PuTTY

March 15th, 2012 Comments off

This tutorial is aimed at Windows users and focuses on PuTTY as our SSH client of choice.

Are you stuck behind a firewall or looking to add some privacy to your browsing? Whenever I’m off my own network I fire up an SSH tunnel back to my own servers and send all my browsing information through it. Why? Because big brother may be watching, but I can bet you someone even worse is trying to. Also, it could be incriminating if people knew how often I was checking my 9th (out of 10) place Fantasy Football team stats.

What is Tunneling? The Over Simplified Definition

When your browser (or other client) requests a webpage (or anything off the Internet) it sends a request from your computer through a series of routers, switches, firewalls, and servers owned and monitored by other people, companies, and ISPs until it reaches its destination, then follows the same (or similar) path back to your machine with the kitten pictures you asked for.

Tunneling bypasses some of the rules that these companies or ISPs may be enforcing on you by creating a direct, encrypted, connection to your tunnel server that can’t be easily peered into by prying eyes. This means that web pages that are blocked can be seen and passwords that are sent can’t be looked at.

For a much better definition, please see Wikipedia

Install PuTTY

There are other SSH clients and tools that are designed specifically for SSH tunneling and SOCKS proxying. I prefer this way because PuTTY also gives you an SSH client, which you should no doubt be in possession of anyways.

  1. Download PuTTY here (choose the archive version)
  2. Make a new directory at C:\bin
  3. Extract the contents of the putty archive into C:\bin
  4. An extra step that’s not really necessary- Add C:\bin to your Windows system path (if you don’t know how, skip this or google it)

Configuring PuTTY

  1. Fire up the client and enter the hostname and portPuTTY Hostname
  2. Type in a title under Saved Sessions and press Save
  3. On the left side, go to Connection->SSH->Tunnels
  4. In Source Port enter 8080 (this can be configured to be whatever you want, just remember it)
  5. Choose the Dynamic radio button under DestinationPuTTY Tunnel
  6. Press Add, you should then see D8080 in the box above
  7. Go back to Session on the left side and then press Save to save the changes

SOCKS Proxy

To utilize the tunnel to its full benefit, you need to set up a SOCKS proxy in your browser. Will describe how to use the FoxyProxy proxy switching plugin. It works for both FireFox and Chrome on Windows, which are really the only browsers you should be using.

  1. Download FoxyProxy for your browser here.
  2. Once installed, go to the FoxyProxy optionsFoxy Proxy
  3. Click Add New
  4. Click the General tab and enter a name in the Proxy Name box
  5. Make sure Perform remote DNS lookups on hostnames loading through this proxy is checked – we’ll discuss this a little later
  6. Select the Proxy Details tab
  7. Enter localhost in the Host box
  8. Enter 8080 in the Port box
  9. Check SOCKS Proxy? and make sure the SOCKS v5 radio is checked
  10. Press Ok to save
  11. At the Select Mode drop down, choose your freshly created SOCKS Proxy

Conclusion

So long as your PuTTY SSH connection remains connected your proxy tunnel will be open and you will be browsing the internet just as you had before, except without a lot of restrictions placed by firewalls and greater security.

Final Note: Secure DNS Resolution

As far as I understand it Chrome will automatically use your SOCKS proxy for DNS resolution, but Firefox doesn’t by default. This means that firewalls or DNS servers could still block requests to certain websites because they will refuse to tell your browser or client how to look the remote server up. FoxyProxy should fix this due to the installation steps we took, but it doesn’t guarantee that your IM messenger, other browsers, or other internet clients will be able to securely resolve DNS requests when using the SOCKS proxy. For more information on exactly what DNS is, browse over to Wikipedia

I recommend a 3rd party DNS service like OpenDNS to further enhance the safety, speed, and security of your DNS lookups. They can protect from malware and other bad things, but they can also provide you with a ‘less restricted’ internet.

NSLog Conditionally in Debug Mode and NSLog Macros

March 6th, 2012 Comments off

Using Objective-C Macros to Conditionally Log

During the course of developing and debugging my first iOS apps I’ve realized that there has to be at least a semi-decent way of using log statements for debugging messages as well as error messages without a lot of code overhead and manual changes when switching between building for Release and Debug.

Using macros and compiler settings, you too can quickly separate the statements out and streamline your debugging/logging code.

Creating Your Macros

Find the -Prefix.pch header file for your project and open it for editing. If your project’s name is MyProject you will look for MyProject-Prefix.pch.

Add the following lines to the end of your Prefix header file:

// Macro wrapper for NSLog only if debug mode has been enabled
#ifdef MA_DEBUG
    #define AshDebugLog(fmt,...) NSLog(@"%@",[NSString stringWithFormat:(fmt), ##__VA_ARGS__]);
#else
    // If debug mode hasn't been enabled, don't do anything when the macro is called
    #define AshDebugLog(...)
#endif 

// Log using the same parameters above but include the function name and source code line number in the log statement
#ifdef MA_DEBUG
    #define AshDebugLogDetailed(fmt, ...) NSLog((@"Func: %s, Line: %d, " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
    #define AshDebugLogDetailed(...)
#endif

// This macro will create a detailed log message and run even during a production build
#define AshDetailedLog(fmt, ...) NSLog((@"Func: %s, Line: %d, " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

What We Did

I have prefixed each macro with Ash so that there is no confusing them as macros I created. As you can also see, we have created a few different ways to log. We have a standard wrapper for NSLog that we will call instead of NSLog that will only fire if we’ve built using a debug mode flag. We also have two different methods for creating detailed log messages on the fly that will include our log message along with the function and line number the message originates from. The nice thing about these macros is that you can easily change the string format to log in any way that you want.

XCode Settings

  1. Select your project in the Xcode explorer/left pane

    XCode Project

    Xcode 4.2

     
  2. Select Build Settings in the Xcode center window
  3. Search for preprocessor in the Build Settings section and add DEBUGGING as a Debug Preprocessor Macro.

    Xcode Preprocessor Build Settings

    Set the Debug preprocessor settings

Reduce Three20 Compile Time for iOS (Making Static Libraries)

February 18th, 2012 Comments off

In using Three20 with Xcode 4, I have found life to be a little more difficult than in Xcode 3.

Project changes have required me to fiddle with the project/target compile settings in order to get my project to build correctly, often seeing the dreaded “Three20/Three20.h” file not found error, and not being able to build for archive have all been recurring issues that I’ve faced while developing some pretty simple iOS apps utilizing the Three20 project.

Finally, when the project is building correctly, I spend almost all my compile time building all the Three20 libraries. In search of a better way I stumbled upon a stackoverflow question, and then later on a blog post that have essentially gotten rid of all these hassles for me.

Step 1: How to build any library for all platforms

  • Open an existing static library project.
  • Select the project file on the top, and then select the target you want to build.
  • Go into the Build Phases section
  • Add a new “Run Script” build phase
  • In this phase, paste the following script:
# Version 2.0 (updated for Xcode 4, with some fixes)
# Changes:
#    - Works with xcode 4, even when running xcode 3 projects (Workarounds for apple bugs)
#    - Faster / better: only runs lipo once, instead of once per recursion
#    - Added some debugging statemetns that can be switched on/off by changing the DEBUG_THIS_SCRIPT variable to "true"
#    - Fixed some typos
# 
# Purpose:
#   Create a static library for iPhone from within XCode
#   Because Apple staff DELIBERATELY broke Xcode to make this impossible from the GUI (Xcode 3.2.3 specifically states this in the Release notes!)
#   ...no, I don't understand why they did this!
#
# Author: Adam Martin - http://twitter.com/redglassesapps
# Based on: original script from Eonil (main changes: Eonil's script WILL NOT WORK in Xcode GUI - it WILL CRASH YOUR COMPUTER)
#
# More info: see this Stack Overflow question: http://stackoverflow.com/questions/3520977/build-fat-static-library-device-simulator-using-xcode-and-sdk-4
#################[ Tests: helps workaround any future bugs in Xcode ]########
#
DEBUG_THIS_SCRIPT="false"
if [ $DEBUG_THIS_SCRIPT = "true" ]
then
echo "########### TESTS #############"
echo "Use the following variables when debugging this script; note that they may change on recursions"
echo "BUILD_DIR = $BUILD_DIR"
echo "BUILD_ROOT = $BUILD_ROOT"
echo "CONFIGURATION_BUILD_DIR = $CONFIGURATION_BUILD_DIR"
echo "BUILT_PRODUCTS_DIR = $BUILT_PRODUCTS_DIR"
echo "CONFIGURATION_TEMP_DIR = $CONFIGURATION_TEMP_DIR"
echo "TARGET_BUILD_DIR = $TARGET_BUILD_DIR"
fi
#####################[ part 1 ]##################
# First, work out the BASESDK version number (NB: Apple ought to report this, but they hide it)
#    (incidental: searching for substrings in sh is a nightmare! Sob)
SDK_VERSION=$(echo ${SDK_NAME} | grep -o '.\{3\}$')
# Next, work out if we're in SIM or DEVICE
if [ ${PLATFORM_NAME} = "iphonesimulator" ]
then
OTHER_SDK_TO_BUILD=iphoneos${SDK_VERSION}
else
OTHER_SDK_TO_BUILD=iphonesimulator${SDK_VERSION}
fi
echo "XCode has selected SDK: ${PLATFORM_NAME} with version: ${SDK_VERSION} (although back-targetting: ${IPHONEOS_DEPLOYMENT_TARGET})"
echo "...therefore, OTHER_SDK_TO_BUILD = ${OTHER_SDK_TO_BUILD}"
#
#####################[ end of part 1 ]##################
#####################[ part 2 ]##################
#
# IF this is the original invocation, invoke WHATEVER other builds are required
#
# Xcode is already building ONE target...
#
# ...but this is a LIBRARY, so Apple is wrong to set it to build just one.
# ...we need to build ALL targets
# ...we MUST NOT re-build the target that is ALREADY being built: Xcode WILL CRASH YOUR COMPUTER if you try this (infinite recursion!)
#
#
# So: build ONLY the missing platforms/configurations.
if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: I am NOT the root invocation, so I'm NOT going to recurse"
else
# CRITICAL:
# Prevent infinite recursion (Xcode sucks)
export ALREADYINVOKED="true"
echo "RECURSION: I am the root ... recursing all missing build targets NOW..."
echo "RECURSION: ...about to invoke: xcodebuild -configuration \"${CONFIGURATION}\" -target \"${TARGET_NAME}\" -sdk \"${OTHER_SDK_TO_BUILD}\" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO"
xcodebuild -configuration "${CONFIGURATION}" -target "${TARGET_NAME}" -sdk "${OTHER_SDK_TO_BUILD}" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
ACTION="build"
#Merge all platform binaries as a fat binary for each configurations.
# Calculate where the (multiple) built files are coming from:
CURRENTCONFIG_DEVICE_DIR=${SYMROOT}/${CONFIGURATION}-iphoneos
CURRENTCONFIG_SIMULATOR_DIR=${SYMROOT}/${CONFIGURATION}-iphonesimulator
echo "Taking device build from: ${CURRENTCONFIG_DEVICE_DIR}"
echo "Taking simulator build from: ${CURRENTCONFIG_SIMULATOR_DIR}"
CREATING_UNIVERSAL_DIR=${SYMROOT}/${CONFIGURATION}-universal
echo "...I will output a universal build to: ${CREATING_UNIVERSAL_DIR}"
# ... remove the products of previous runs of this script
#      NB: this directory is ONLY created by this script - it should be safe to delete!
#rm -rf "${CREATING_UNIVERSAL_DIR}"
#mkdir "${CREATING_UNIVERSAL_DIR}"
#
echo "lipo: for current configuration (${CONFIGURATION}) creating output file: ${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}"
lipo -create -output "${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}" "${CURRENTCONFIG_DEVICE_DIR}/${EXECUTABLE_NAME}" "${CURRENTCONFIG_SIMULATOR_DIR}/${EXECUTABLE_NAME}"
#########
#
# Added: StackOverflow suggestion to also copy "include" files
#    (untested, but should work OK)
#
if [ -d "${CURRENTCONFIG_DEVICE_DIR}/usr/local/include" ]
then
mkdir -p "${CREATING_UNIVERSAL_DIR}/usr/local/include"
# * needs to be outside the double quotes?
cp "${CURRENTCONFIG_DEVICE_DIR}/usr/local/include/"* "${CREATING_UNIVERSAL_DIR}/usr/local/include"
fi
fi

The following code, which was copied directly from the blog post linked above, tells Xcode to compile all the targets for both Device and Simulator. The resulting output will be a .a library file for use in other projects.

Applying this to Three20

  • Go into {Three20 Root Directory}/src/Three20 and open Three20.xcodeproj
  • Select the Three20 target and add the above script into the appropriate build phase
  • Nothing needs to be done to the “Three20UnitTests” target, we won’t be using it for anything.
  • Expand the Dependencies folder for your Three20 project, in the files list on the left side of Xcode
  • Add the same script phase you did before in all of these dependent projects.
  • Do this for every dependency project. If you don’t do this, Xcode will produce all .a libraries, but only the main Three20 library will be created for all devices and they all need to be created for all devices.
  • Once you have added the script build phase to all projects and dependencies, build the project (and be patient).

Giving Due Credit

Had I not stumbled onto Christos Sotiriou‘s blog post I probably could never have figured this out from end to end on my own. He even offers a direct download to compiled libraries and headers if you want to just get up and running.

Categories: Tutorial Tags: , ,

Authentication Using WordPress and Zend Framework

December 19th, 2011 Comments off

I recently had the need to implement a Zend Framework web app that could authorize against WordPress without necessarily using WordPress as the front end. I was very relieved to find out it was quite easy to do!

In your application’s index.php (typically found at public/index.php) you need to include the WordPress header file to make sure you have access to the WordPress functions later in your application:

defined('WORDPRESS_DIR') || define('WORDPRESS_DIR', realpath(dirname(__FILE__) . '/wordpress'));
require_once(WORDPRESS_DIR . '/wp-blog-header.php');

I have the following code in my LoginController.php (application/modules/public/controllers/LoginController.php) file.

doWordpressAuth function

protected function doWordpressAuth($username, $password)
{

    // Optional - Sanitize user input in this method
    // or handle it before calling authenticate
    $username = sanitize_user($username);
    $password = trim($password);

    $creds = array('user_login' => $username,
                   'user_password' => $password,
                   'remember' => true
            );
    $user = wp_signon($creds, false);

    if($user == null)
    {
        // Invalid username or password
        return null;
    }

     $ignore = array('empty_username', 'empty_password');
     if((is_wp_error($user))&&(!(in_array($user->get_error_code(),$ignore))))
     {
        // Login failed due to some error...
        return null;
     }

     return $user;
}

IndexAction

public function indexAction()
{
    $request = $this->getRequest();
    if(!$request->isPost()){ return $this->render('index'); }

    $username = $request->getParam('username');
    $password = $request->getParam('userpass');

    if((is_null($username))||(is_null($password)))
    {
        $this->addError('Missing username or password');
        return $this->render('index');
    }
    // Enforce username and password minimum lengths
    elseif((strlen($username) < 4)||(strlen($password) < 6))
    {
        $this->addError('Invalid username or password');
        return $this->render('index');
    }

    // Use wordpress for authentication
    if(AC_Utilities::getApplicationSetting('use_wp_auth') == true)
    {
        $user = $this->doWordpressAuth($username, $password);
        /**
         * ...
         * Various user detail handling procedures...
         * ...
         */
        $session->user = $user;
    }
    // Use built-in authentication mechanism
    else
    {
        /**
         * ...
         * Use built in login mechanism ...
         * ...
         */
    }
    // Logged in, redirect to the IndexController
    $this->_helper->redirector('index','index');
}

How to Specify Non-String PHP Data Types in Zend Config XML and INI Files

September 7th, 2011 Comments off

Zend Config INI and Zend Config XML are adapters in the Zend Framework that allow you to store your application or website configuration data (such as database connector information and salt values) in an easy to interpret text file (I happen to prefer INI files over XML because INI is more terse).

The biggest downside to these files is that they don’t store PHP data types or values like NULL, FALSE, or TRUE, and you can’t specify an int, double, or float, the adapters only return strings.

Here is the recursive code for converting all your values:

public static function convertConfigValuesFromString($config)
    {
        foreach($config as $key => $value)
        {
            if(is_string($value))
            {
                switch($value)
                {
                    case 'BOOL_FALSE':
                        $config[$key] = false;
                        break;
                    case 'BOOL_TRUE':
                        $config[$key] = true;
                        break;
                    case 'CONST_NULL':
                        $config[$key] = null;
                        break;
                    default:
                        if(substr($value,0,4) == 'INT_')
                        {
                            $config[$key] = (int) substr($value,4);
                        }
                        elseif(substr($value,0,4) == "DBL_")
                        {
                            $config[$key] = (double) substr($value,4);
                        }
                        elseif(substr($value,0,4) == "FLT_")
                        {
                            $config[$key] = (float) substr($value,4);
                        }
                        break;
                }
            }
            elseif(is_array($value))
            {
                $config[$key] = self::convertConfigValuesFromString($value);
            }
        }
        return $config;
    }

Here is how I use it in my Bootstrap.php file in my Zend Framework application:

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected $_namespace = 'Ashurex';
    protected $_config;

    ... other code ...

    protected function _initConfig()
    {        
        // Use the default mechanisms built into the bootlstrap
        // for reading in the app configuration
        $config = $this->getOptions();

        $config = Ashurex_Utilities::convertConfigValuesFromString($config);   
   
        // After gathering and assigning the 
        // correct data types to our config values
        // Turn into an instance of Zend_Config for later use
        $config = new Zend_Config($config);
        // Store the config in the registry
        Zend_Registry::set('config', $config);

        $this->_config = $config;
        return $config;
    }

    ... other code ...

}

The following config file will end up looking like the following array (before turning it into a Zend_Config object)

[default]
phpSettings.date.timezone = "America/Los_Angeles"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
resources.modules[] =
resources.view.doctype = "HTML5"
app.debug.enabled = "BOOL_TRUE"
resources.db.adapter = PDO_MYSQL

[development : default]
resources.db.params.host = "localhost"
resources.db.params.username = "dbuser"
resources.db.params.password = "dbpassword"
resources.db.params.dbname = "dbname"
app.integer = "INT_1234567890"
app.double = "DBL_123456789012345.678"
app.float = "FLT_12.0000001"
session.name = "session_name"
array
  'phpSettings' => 
    array
      'date' => 
        array
          'timezone' => string 'America/Los_Angeles' (length=19)
  'bootstrap' => 
    array
      'path' => string '/var/www/html/application/Bootstrap.php' (length=50)
  'resources' => 
    array
      'modules' => 
        array
          0 => string '' (length=0)
      'view' => 
        array
          'doctype' => string 'HTML5' (length=5)
      'db' => 
        array
          'adapter' => string 'PDO_MYSQL' (length=9)
          'params' => 
            array
              ...
  'app' => 
    array
      'debug' => 
        array
          'enabled' => boolean true
      'integer' => int 1234567890
      'double' => float 1.2345678901235E+14
      'float' => float 12.0000001
  'session' => 
    array
      'name' => string 'session_name' (length=12)

Using mysqli Extension to Query MySQL from PHP Instead of the mysql Extension

August 11th, 2011 Comments off

I was answering a very basic question on stackoverflow today that boiled down to “How do I query mysql from PHP using a user input” and was horrified to see the first two answers.

The first answer went along the lines of:

$result = mysql_query("SELECT * FROM table WHERE field = '". $_POST['input'] ."'");
while($row = mysql_fetch_array($result)){
    //do stuff
}

This is bad. Very bad. Very, very bad.
This is the kind of thing that allowed (maybe a bit of hyperbole, but stick with me) Sony to be brought to its knees. This is how all your user data gets stolen. This is how Anonymous makes you look like a fascist who wants to eat babies. It’s bad. It did come from someone with a pretty low score on SO, but I’m living proof that a low score on SO doesn’t mean you don’t know what you’re doing.

Why?

The first MAJOR problem is: You are taking direct, unsanitized user input. You have not validated that the input is correct, even relates to what you are having them input, or is safe.
By taking direct input straight from the user (by directly using the $_POST variable nonetheless) they could attack via sql injection at worst, and the $_POST field may not exist, giving you an error, at best.

The second problem is the use of the mysql extension in PHP. According to the manual, the mysql extension should only be used in 4.1.3 and lower, anything newer should be using mysqli for improved performance and security.

I have heard there are some issues with mysqli in certain cases that essentially require the use of the mysql_ extension to get around them. As far as I know, these are few in number and getting better by the day. I personally, haven’t ever had a problem with mysqli.

On to a more correct example:

$db = new mysqli("localhost","user","password","database");

if(mysqli_connect_error())
{
    printf("Connection failed:%s \n",mysqli_connect_error());
    exit();
}

$input = mysqli_real_escape_string($db, $_POST['search']);

/* 
 * Validate that $input is correct after escaping
 * Implement your validation below!
 */

if($result = $db->query("SELECT * FROM table WHERE field = $input", MYSQLI_ASSOC))
{
    while($row = $result->fetch_object())
    {
        // $row is an associative array
        // Do something here
    }
}
$db->close();

What’s better about this code?

First, it’s not perfect. You could pick it apart, but it’s a good example of where to start and I wrote it in about 45 seconds.
It shows:

  • Connecting to the mysql database
  • Ensuring a connection occured and handling the mysql connection error
  • Querying the database
  • Escaping user input AND THEN validating
  • Iterating through the mysql results
  • Closing the database connection (people never remind beginners to do this)!

The basics shouldn’t be so complicated that it takes two months to make heads or tails of what your code really does (I’m looking at you Zend Framework), but it should start with a good explanation of the big picture.

Categories: Programming, Tutorial Tags: , , ,

Removing ShareThis from your WordPress Front Page

July 7th, 2011 Comments off

After installing the ShareThis social plugin for WordPress I was surprised to find that there isn’t an easy option to exclude the social links from showing up on the front page. Luckily, it’s as easy as inserting a small bit of code into the sharethis.php plugin file.
On my system the file is located at

{wordpress root directory}/wp-content/plugins/share-this/sharethis.php

Open up the file in your favorite editor and go to nearly the bottom of the file and find the function (around line 601 in the version that I have) st_makeEntries

Add in the following code

if(is_front_page()){ return ''; }

So that the beginning of your function looks like this:

function st_makeEntries(){
        if(is_front_page()){ return ''; }
        global $post;
        ... the rest of the function follows ...

We are basically bypassing the code that builds the social badges and returning nothing instead of the HTML that the code would otherwise build.

Categories: Tutorial Tags: , , ,