. */ /** * Methods return this if they succeed */ if (@defined('AA_PP_DEBUG')) return; define('AA_PP_DEBUG', 1); /** * Methods return this if they succeed */ define('ACLF', chr(13) . chr(10)); register_activation_hook(__FILE__, 'aa_pp_activate'); register_deactivation_hook(__FILE__, 'aa_pp_deactivate'); add_action('admin_menu', 'aa_pp_setup_options'); if (strpos($_SERVER['REQUEST_URI'], basename(__FILE__)) !== false) add_action('admin_head', 'aa_pp_admin_header'); /** * aa_pp_admin_header() * * @return */ function aa_pp_admin_header() { global $wpdb, $aa_PP, $aa_SIDS; if (!current_user_can(8)) die(__("You are not allowed to be here without upload permissions")); if (!user_can_access_admin_page()) { do_action('admin_page_access_denied'); wp_die(__('You do not have sufficient permissions to access this page.')); } $aa_PP = get_option('askapache_password_protect'); $aa_SIDS = get_option('askapache_password_protect_sids'); $action = ''; foreach (array('activate-selected', 'deactivate-selected', 'delete-selected', 'move-read', 'move-setup', 'move-sid', 'move-test', 'move-contact') as $action_key) { if (isset($_POST[$action_key])) { $action = $action_key; break; } } if (isset($_GET['deactivate-sid'])) $action = 'deactivate-sid'; if (isset($_GET['activate-sid'])) $action = 'activate-sid'; if (isset($_POST['step'])) $aa_PP['step'] = $_POST['step']; if (!empty($action)) { switch ($action) { case 'move-setup': check_admin_referer('askapache-move-area'); $aa_PP['step'] = 'setup'; break; case 'move-sid': check_admin_referer('askapache-move-area'); $aa_PP['step'] = 'sid'; break; case 'move-read': check_admin_referer('askapache-move-area'); $aa_PP['step'] = 'read'; break; case 'move-test': check_admin_referer('askapache-move-area'); $aa_PP['step'] = 'welcome'; break; case 'move-contact': check_admin_referer('askapache-move-area'); $aa_PP['step'] = 'contact'; break; case 'activate-sid': $sid = (int)$_GET['activate-sid']; check_admin_referer('activate-sid_' . $sid); aa_pp_activate_sid($sid); break; case 'deactivate-sid': $sid = (int)$_GET['deactivate-sid']; check_admin_referer('deactivate-sid_' . $sid); aa_pp_deactivate_sid($sid); break; case 'activate-selected': check_admin_referer('askapache-bulk-sids'); break; case 'deactivate-selected': check_admin_referer('askapache-bulk-sids'); break; } } if ($_SERVER['REQUEST_METHOD'] == 'POST') aa_pp_get_post_values(); } /** * aa_pp_get_post_values() * * @return */ function aa_pp_get_post_values() { global $aa_PP, $aa_SIDS; if (isset($_POST['a_user']) && !empty($_POST['a_user'])) $aa_PP['user'] = preg_replace('|[^a-z0-9 _.\-@]|i', '', strip_tags($_POST['a_user'])); if (isset($_POST['a_authdomain']) && !empty($_POST['a_authdomain'])) $aa_PP['authdomain'] = $_POST['a_authdomain']; if (isset($_POST['a_authtype'])) { if (in_array(strtolower($_POST['a_authtype']), array('digest', 'basic'))) $aa_PP['authtype'] = $_POST['a_authtype']; if (strtolower($aa_PP['authtype']) == 'digest') $aa_PP['algorithm'] = 'md5'; } if (isset($_POST['a_authname']) && !empty($_POST['a_authname'])) { $aa_PP['authname'] = preg_replace('|[^a-z0-9 _.=\-@]|i', '', strip_tags($_POST['a_authname'])); if (strlen($aa_PP['authname']) > 65) $aa_PP['authname'] = substr($aa_PP['authname'], 0, 65); } if (isset($_POST['a_algorithm'])) { if (in_array(strtolower($_POST['a_algorithm']), array('crypt', 'md5', 'sha1'))) $aa_PP['algorithm'] = strip_tags($_POST['a_algorithm']); } if (isset($_POST['a_authuserfile'])) { $d = strip_tags($_POST['a_authuserfile']); if (!empty($d) && file_exists($d) && @touch($d)) { $aa_PP['authuserfile'] = $d; } } if (isset($_POST['a_pass'])) { $htpasswd = aa_pp_hashit($aa_PP['authtype'], $aa_PP['user'], $_POST['a_pass'], $aa_PP['authname']); aa_pp_file_put_c($aa_PP['authuserfile'], $htpasswd, true); if (isset($_POST['aa_protect_wpadmin'])) aa_pp_activate_sid(900000, $aa_PP['admin_htaccess']); if (isset($_POST['aa_protect_wplogin'])) aa_pp_activate_sid(800000, $aa_PP['root_htaccess']); echo ''; } update_option('askapache_password_protect', $aa_PP); $aa_SIDS = get_option('askapache_password_protect_sids'); } /** * aa_pp_gen_sid() * * @param mixed $incoming * @return */ function aa_pp_gen_sid($incoming) { global $aa_PP, $aa_SIDS; if (strtolower($aa_PP['authtype']) == 'basic') $replacement = 'AuthType %authtype%%n%AuthName "%authname%"%n%AuthUserFile %authuserfile%%n%Require user %user%'; else $replacement = 'AuthType %authtype%%n%AuthName "%authname%"%n%AuthDigestDomain %authdomain%%n%AuthDigestFile %authuserfile%%n%Require user %user%'; $aa_S = array('%n%', '%authname%', '%user%', '%authuserfile%', '%relative_root%', '%scheme%', '%authdomain%', '%host%', '%authtype%', '%generate_auth%'); $aa_R = array("\n", $aa_PP['authname'], $aa_PP['user'], $aa_PP['authuserfile'], $aa_PP['root_path'], $aa_PP['scheme'], $aa_PP['authdomain'], $aa_PP['host'], $aa_PP['authtype'], $replacement); return str_replace($aa_S, $aa_R, str_replace($aa_S, $aa_R, $incoming)); } /** * aa_pp_deactivate_sid() * * @param mixed $sid * @param mixed $file * @return */ function aa_pp_deactivate_sid($sid, $file = false) { global $aa_PP; if (!$file) $file = $aa_PP['root_htaccess']; if ((int)$sid == 900000) $file = $aa_PP['admin_htaccess']; $file = (@is_readable($file)) ? realpath(rtrim($file, '/')) : rtrim($file, '/'); if (!is_readable($file)) return false; aa_pp_notify("Deleting {$sid} from $file"); $result = array(); if ($markerdata = @explode("\n", @implode('', @file($file)))) { $state = false; if (!$f = @fopen($file, 'w')) return aa_pp_debug("aa_pp_deactivate_sid couldnt fopen {$file}"); $x = false; foreach ($markerdata as $n => $line) { if (strpos($line, "# +SID {$sid}") !== false) $state = true; if (!$state) fwrite($f, $line . "\n"); if (strpos($line, "# -SID {$sid}") !== false) $state = false; } } @$_POST['notice']='Deactivated '.$sid; return fclose($f); } /** * aa_pp_active_sids() * * @param mixed $file * @param string $sid * @return */ function aa_pp_active_sids($file = false, $sid = ' ') { global $aa_PP, $aa_SIDS; $result = array(); $files = array($aa_PP['root_htaccess'], $aa_PP['admin_htaccess']); foreach ($files as $f) { if ($markerdata = @explode("\n", @implode('', @file($f)))) { foreach ($markerdata as $line) { $si = (int)str_replace('# +SID ', '', rtrim($line)); if (strpos($line, "# +SID{$sid}") !== false) $result[] = $si; } } } return array_unique($result); } /** * aa_pp_activate_sid() * * @param mixed $sid * @param mixed $file * @return */ function aa_pp_activate_sid($sid, $file = false) { global $aa_PP, $aa_SIDS; if (!$file) $file = $aa_PP['root_htaccess']; if ((int)$sid == 900000) $file = $aa_PP['admin_htaccess']; aa_pp_notify("activate_sid {$sid} in file {$file}"); $rules = aa_pp_gen_sid(explode("\n", $aa_SIDS[(int)$sid]['Rules'])); @$_POST['notice']='Activate '.$sid; return(!aa_pp_insert_sids($file, $sid, $rules)) ? aa_pp_debug('Failed to activate ' . $sid) : true; } /** * aa_pp_sid_management() * * @return */ function aa_pp_sid_management() { global $aa_PP, $aa_SIDS; ?>






' . __('Activate') . ''; } else { $action_links[] = '' . __('Deactivate') . ''; } if ($is_active) $st = 'active'; else $st = ' '; echo "'; } ?>
{$plugins[$sid]['Name']} {$plugins[$sid]['Version']}

{$plugins[$sid]['Description']}

AskApache .htaccess Tutorial


Warning
Many of these modules can result in disabling or blocking other parts of your site. Please don't experiment on a production server until the upgrade comes out in a couple weeks. Let me know of any bugs.. webmaster@

Upcoming
This version was released early for all you who wanted it. As you can see, its been refactored from top to bottom.

The SID Module Redesigned

I'm finally mostly happy with the system now used by this plugin to update/modify/and use the different modules. The old code just wasn't future-proofed enough. This new version is based very much off of the WordPress Plugins code, so it is future proofed.

This "Improvements" page is the start of whats to come, basically each of the security modules (and there are a LOT of great mod_security ones coming) will have their own very basic settings. So you can tweak the settings. If someone finds an improvement they can send it for review. New ideas and modules can be submitted here also.

Blog Root .htaccess

';foreach($rules as $line){ echo htmlentities($line)."\n"; } } ?>

Test for Compatibility and Capability

First we need to run a series of tests on your server to determine what capabilities your site has and also to locate any potential installation problems.

The tests will be run on temporary files I'll create in your /wp-content/askapache/ folder. They will create .htaccess and .htpasswd files in that temp location and then use fsockopen networking functions to query those files. This tells us exactly how your server handles .htaccess configurations, HTTP authentication schemes, Apache Module capability, etc..

Several tests send specially crafted HTTP requests which are designed to elicit very specific HTTP Protocol Responses to accurately determine your servers capabilities.

Other important checks will run: file permissions, function availability, much more boring testing. The tests are fast and you can re-run them whenever you want. If you'd like to see the action, define AA_PP_DEBUG to true in the source of this file. Good Luck!

Setup Password Protection

Create User

Turn On / Off

Authentication Scheme

Choose Scheme




This is the mechanism by which your credentials are authenticated (Digest is strongly preferred)

Authentication Settings


Use a location inaccessible from a web-browser if possible. Do not put it in the directory that it protects.

The authname or "Realm" serves two major functions. First, the client often presents this information to the user as part of the password dialog box. Second, it is used by the client to determine what password to send for a given authenticated area.

One or more URIs which are in the same protection space (i.e. use the same authname and username/password info). The URIs may be either absolute or relative URIs. Omitting causes client to send Authorization header for every request.

Encryption Preferences

Password File Algorithm



Note I do not store or save your password anywhere, so you will need to type it in each time you update this page.. for now.

0; $i -= 16) $text .= substr($bin, 0, min(16, $i)); for ($i = $len; $i > 0; $i >>= 1) $text .= ($i &1) ? chr(0) : $pass{0}; $bin = pack("H32", md5($text)); for ($i = 0; $i < 1000; $i++) { $new = ($i &1) ? $pass : $bin; if ($i % 3) $new .= $saltt; if ($i % 7) $new .= $pass; $new .= ($i &1) ? $bin : $pass; $bin = pack("H32", md5($new)); } for ($i = 0; $i < 5; $i++) { $k = $i + 6; $j = $i + 12; if ($j == 16) $j = 5; $tmp = $bin[$i] . $bin[$k] . $bin[$j] . $tmp; } $tmp = chr(0) . chr(0) . $bin[11] . $tmp; $tmp = strtr(strrev(substr(base64_encode($tmp), 2)), "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); $hash = $user . ':$apr1$' . $saltt . '$' . $tmp; break; } return $hash; } /** * aa_pp_insert_mark() * * @param mixed $file * @param mixed $marker * @param mixed $insertion * @param mixed $backup * @return */ function aa_pp_insert_mark($file, $marker, $insertion, $backup = false) { global $aa_PP; $file = (@is_readable($file)) ? realpath(rtrim($file, '/')) : rtrim($file, '/'); if (!is_writable($file) && @!chmod($file, 0666) && !@touch($file)) return aa_pp_debug("aa_pp_insert_mark could not write, create, or touch {$file}"); if ($backup) $backedup = aa_pp_backup($file, $file . '-' . time()); aa_pp_notify("Inserting {$marker} array to {$file}"); $oldone = $foundit = false; $out = array(); if (!is_array($insertion) || (is_array($insertion) && count($insertion) < 1)) { aa_pp_notify("aa_pp_insert_mark1 called without array, creating one for {$marker}"); $my = array("# +{$marker}", "", "# -{$marker}"); } else { $my = array(); $my[] = "# +{$marker}"; foreach ($insertion as $l) $my[] = $l; $my[] = "# -{$marker}"; } if (!$f = @fopen($file, 'w')) return aa_pp_debug("aa_pp_insert_mark couldnt fopen {$file}"); $pr = join("\n", $my); if (!@fwrite($f, $pr, strlen($pr))) return aa_pp_debug("aa_pp_insert_mark couldnt fwrite {$file}"); fwrite($f, $out, strlen($out)); fclose($f); return true; } /** * aa_pp_insert_sids() * * @param mixed $file * @param mixed $marker * @param mixed $insertion * @param mixed $backup * @return */ function aa_pp_insert_sids($file, $marker, $insertion, $backup = false) { global $aa_PP; $file = (@is_readable($file)) ? realpath(rtrim($file, '/')) : rtrim($file, '/'); if (!is_writable($file) && @!chmod($file, 0666) && !@touch($file)) return aa_pp_debug("aa_pp_insert_sids could not write, create, or touch {$file}"); if ($backup) $backedup = aa_pp_backup($file, $file . '-' . time()); aa_pp_notify("Inserting {$marker} array to {$file}"); $oldone = $foundit = false; $out = array(); if (!is_array($insertion) || (is_array($insertion) && count($insertion) < 1)) { aa_pp_notify("aa_pp_insert_sids called without array, creating one for {$marker}"); $my = array("# +SID {$marker}", "", "# -SID {$marker}"); } else { $my = array(); $my[] = "# +SID {$marker}"; foreach ($insertion as $l) $my[] = $l; $my[] = "# -SID {$marker}"; } $out = array(); $markerdata = (is_writable(dirname($file)) && touch($file)) ? @explode("\n", @implode('', @file($file))) : false; foreach ($markerdata as $line) if (strpos($line, '# +ASKAPACHE PASSPRO') !== false) $oldone = true; if (!$oldone) { $ot = array('# +ASKAPACHE PASSPRO ' . $aa_PP['plugin_data']['Version'], '#######################################################', '# __ __', '# ____ ______/ /______ _____ ____ ______/ /_ ___', '# / __ `/ ___/ //_/ __ `/ __ \/ __ `/ ___/ __ \/ _ \\', '# / /_/ (__ ) ,< / /_/ / /_/ / /_/ / /__/ / / / __/', '# \__,_/____/_/|_|\__,_/ .___/\__,_/\___/_/ /_/\___/', '# /_/', '# - - - - - - - - - - - - - - - - - - - - - - - - - - -', '# +APRO SIDS', '# -APRO SIDS', '# - - - - - - - - - - - - - - - - - - - - - - - - - - -', '# __ __', '# ____ ______/ /______ _____ ____ ______/ /_ ___', '# / __ `/ ___/ //_/ __ `/ __ \/ __ `/ ___/ __ \/ _ \\', '# / /_/ (__ ) ,< / /_/ / /_/ / /_/ / /__/ / / / __/', '# \__,_/____/_/|_|\__,_/ .___/\__,_/\___/_/ /_/\___/', '# /_/', '#######################################################', '# -ASKAPACHE PASSPRO ' . $aa_PP['plugin_data']['Version']); $jot=array_merge($markerdata,$ot); if (!$f = @fopen($file, 'w')) return aa_pp_debug("aa_pp_insert_sids couldnt fopen {$file}"); $pr = join("\n", $jot); if (!@fwrite($f, $pr, strlen($pr))) return aa_pp_debug("aa_pp_insert_sids couldnt fwrite {$file}"); fclose($f); } if ($markerdata = @explode("\n", @implode('', @file($file)))) { if (!$f = @fopen($file, 'w')) return aa_pp_debug("aa_pp_insert_sids couldnt fopen {$file}"); $state = $s = $found = false; foreach ($markerdata as $line) { if (strpos($line, '-ASKAPACHE PASSPRO') !== false) { fwrite($f, $line); continue; } if (strpos($line, "# +APRO SIDS") !== false) { $s = true; fwrite($f, $line . "\n"); continue; } if (strpos($line, "# -APRO SIDS") !== false) { $s = false; if (!$found) { foreach ($my as $in) fwrite($f, $in . "\n"); } fwrite($f, $line . "\n"); continue; } if (!$s) fwrite($f, $line . "\n"); else { if (strpos($line, "# +SID {$marker}") !== false) $state = true; if (!$state)fwrite($f, $line . "\n"); if (strpos($line, "# -SID {$marker}") !== false) { $state = false; $found = true; foreach ($my as $in){ fwrite($f, $in . "\n"); } } } } fclose($f); } return true; } /** * aa_pp_mkdir() * * @param mixed $dirname * @return */ function aa_pp_mkdir($dirname) { @umask(0); aa_pp_notify("Creating directory {$dirname}"); if (is_dir($dirname) || @wp_mkdir_p($dirname)) return true; if (is_writable($dirname) && @wp_mkdir_p($dirname)) return true; return(@mkdir($dirname, 0777)) ? true : aa_pp_debug("failed to create directory {$dirname}"); } /** * aa_pp_unlink() * * @param mixed $f * @param mixed $backup * @return */ function aa_pp_unlink($f, $backup = false) { @umask(0); $f = (@is_readable($f)) ? realpath(rtrim($f, '/')) : rtrim($f, '/'); aa_pp_notify("Deleting {$f} in aa_pp_unlink"); if (!@file_exists($f)) return true; else { if ($backup) $backedup = aa_pp_backup($f, $f . '-' . time()); return(@chmod($f, 0777) && @unlink($f)) ? true : (@chmod(dirname($f), 0777) && @unlink($f)) ? true : aa_pp_debug("Failed to delete {$f} in aa_pp_unlink"); } } /** * aa_pp_backup() * * @param mixed $f * @param mixed $bf * @return */ function aa_pp_backup($f, $bf) { aa_pp_notify("aa_pp_backup: Backing up {$f} to {$bf}"); if (!@copy($f, $bf)) aa_pp_notify("Failed to backup {$f} to {$bf} using copy"); elseif (!@rename($f, $bf)) return aa_pp_debug("Failed to backup {$f} to {$bf} using rename"); return true; } /** * aa_pp_file_put_c() * * @param mixed $file * @param mixed $content * @param mixed $backup * @return */ function aa_pp_file_put_c($file, $content, $backup = false) { @umask(0); $f = (@is_readable($file)) ? realpath(rtrim($file, '/')) : rtrim($file, '/'); aa_pp_notify("Creating {$f} with aa_pp_file_put_c"); if (file_exists($f) && is_readable($f)) { if ($backup) $backedup = aa_pp_backup($f, $f . '-' . time()); aa_pp_unlink($f, 0); } if (aa_pp_checkfunction("file_put_contents")) return @file_put_contents($f, $content); if (!$fh = @fopen($f, 'wb')) return aa_pp_debug("couldnt fopen {$f}"); if (!@fwrite($fh, $content, strlen($content))) { fclose($fh); return aa_pp_debug("Failed to fwrite to {$f} in aa_pp_file_put_c"); } fclose($fh); return true; } /** * aa_pp_readfile() * * @param mixed $file * @param mixed $g * @return */ function aa_pp_readfile($file, $g = true) { @umask(0); $f = (@is_readable($file)) ? realpath(rtrim($file, '/')) : rtrim($file, '/'); aa_pp_notify("Reading {$f} in aa_pp_readfile"); if (!$fh = @fopen($f, 'rb')) return aa_pp_debug("couldnt fopen {$f}"); if (!$filecontent = @fread($fh, @filesize($f))) { fclose($fh); return aa_pp_debug("Failed to fread {$f} in aa_pp_readfile"); } fclose($fh); if (!$g) return $filecontent; else echo htmlspecialchars($filecontent); } /** * aa_pp_checkfunction() * * @param mixed $func * @return */ function aa_pp_checkfunction($func) { return(!function_exists($func) || @in_array($func, @explode(',', @ini_get('disable_functions')))) ? aa_pp_debug("{$func} disabled or not found") : true; } /** * aa_pp_run_tests() * * @return */ function aa_pp_run_tests() { global $wpdb, $wp_version, $aa_PP, $aa_SIDS; $home = get_option('siteurl'); $hu = str_replace($aa_PP['scheme'] . '://', '', $home); $uri = $aa_PP['scheme'] . '://' . rtrim(str_replace($aa_PP['root_path'], '', $hu), '/'); $test_root_path = $aa_PP['root_path'] . 'wp-content/' . basename($aa_PP['test_dir']) . '/'; $test_url_base = $uri . $test_root_path; $home_path = rtrim(get_home_path(), '/') . '/'; $basic_authuserfile = $home_path . '.htpasswda1'; $digest_authuserfile = $home_path . '.htpasswda2'; $img = pack("H*", "47494638396101000100910000000000ffffffffffff00000021f90405140002002c00000000010001000002025401003b"); $aok = '[ ] '; $fail = '[ ] '; $info = '[ ] '; $warn = '[ ] '; $test_htaccess_rules = array("ErrorDocument 401 {$test_root_path}test.gif", "ErrorDocument 403 {$test_root_path}test.gif", "ErrorDocument 404 {$test_root_path}test.gif", "ErrorDocument 500 {$test_root_path}test.gif", "", 'RedirectMatch 305 ^.*modaliastest$ ' . $home, "", "", "RewriteEngine On", "RewriteBase /", 'RewriteCond %{QUERY_STRING} modrewritetest [NC]', 'RewriteRule .* ' . $home . ' [R=307,L]', "", "", "SecFilterEngine On", 'SecFilter modsecuritytest "deny,nolog,noauditlog,status:503"', "", '', 'AuthName "askapache test"', "AuthUserFile " . $basic_authuserfile, "AuthType Basic", "Require valid-user", '', '', '', 'Deny from All', '', '', '', '', 'AuthType Digest', 'AuthName "askapache test"', "AuthDigestDomain {$test_root_path} {$test_url_base}", "AuthDigestFile " . $digest_authuserfile, 'Require valid-user', '', ''); ?>

Test Results

Compatibility Checks

"; ?>

Checks different software to make sure its compatible with this plugin.

"; echo($wp_version < 2.6) ? $info : $aok; echo " WordPress Version " . $wp_version . ""; $apache_version = preg_replace('|Apache/?([0-9.-]*?) (.*)|i', '\\1', $_SERVER['SERVER_SOFTWARE']); echo "

"; echo(strlen($apache_version) > 1) ? $info : $aok; echo " Apache Version: " . $apache_version . "

"; echo "

"; echo(@version_compare(phpversion(), '5.0.0', '>=')) ? $info : $aok; echo " PHP Version " . phpversion() . "

"; echo "

Required Checks

"; ?>

The tests performed by this page are currently required to determine your servers capabilities to make sure we don't crash your server. The utmost care was taken to make these tests work for everyone running Apache, which is crazy hard because we are testing server configuration settings programmatically from a php binary without access to server configuration settings.

So we achieve this by modifying your server's .htaccess configuration file and then making special HTTP requests to your server which result in specific HTTP responses which tell us if the configuration changes failed or succeeded. The most widely allowed (by web hosts) and compatible 4+5 php function that provides access to sockets is fsockopen, so it is required. The next version will fallback to curl, but if your web host has disabled fsockopen you can bet you don't have curl.

"; echo($atest) ? $aok : $fail; echo " Fsockopen Networking Functionality"; echo "

File Permission Tests

"; ?>

If any of these checks fail this plugin will not work. Both your /.htaccess and /wp-admin/.htaccess files must be writable for this plugin, those are the only 2 files this plugin absolutely must be able to modify. If any of the other checks fail you will need to manually create a folder named askapache in your /wp-content/ folder and make it writable.

"; echo($atest) ? $aok : $fail; echo " /wp-admin/.htaccess file writable"; $htaccess_test2 = $atest = (@is_writable($aa_PP['root_htaccess']) || @touch($aa_PP['root_htaccess'])) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " /wp-admin/.htaccess file writable

"; $atest = (aa_pp_mkdir($aa_PP['test_dir'])) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " Creating test folder

"; $atest = (@is_writable($aa_PP['test_dir']) || @chmod($aa_PP['test_dir'], 766)) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " Test folder writable

"; $atest = (aa_pp_insert_mark($aa_PP['test_dir'] . '/.htpasswda1', 'AskApache PassPro', array())) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " Basic Auth htpasswd file writable

"; $atest = (aa_pp_insert_mark($aa_PP['test_dir'] . '/.htpasswda2', 'AskApache PassPro', array())) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " Digest Auth htpasswd file writable

"; $atest = (aa_pp_insert_sids($aa_PP['test_dir'] . '/.htaccess', 'Test', $test_htaccess_rules)) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " .htaccess test file writable

"; echo "

Encryption Function Tests

"; ?>

Your php installation should have all of these. The md5 is the only one absolutely required, otherwise I can't create the neccessary password files for you.

"; echo($atest) ? $aok : $warn; echo " CRYPT Encryption Function Available"; $aa_PP['md5_support'] = $atest = (aa_pp_checkfunction('md5')) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " MD5 Encryption Function Available

"; $aa_PP['sha1_support'] = $atest = (aa_pp_checkfunction('sha1')) ? 1 : 0; echo "

"; echo($atest) ? $aok : $warn; echo " SHA1 Encryption Function Available

"; echo "

.htaccess Capabilities

"; ?>

These tests determine with a high degree of accuracy whether or not your server is able to handle .htaccess files, and also checks for various Apache modules that extend the functionality of this plugin. The 2 modules you really want to have are mod_rewrite and mod_auth_digest. In future versions of this plugin, we will be utilizing the advanced security features of mod_security more and more, so if you don't have it, bug your web host about it non-stop ;)

"; echo($atest) ? $aok : $fail; echo " Creating .htaccess test files"; $tester = new AskApache_Net; $aa_PP['htaccess_support'] = $atest = ($tester->sockit("{$test_url_base}test.gif") == 200) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " .htaccess files allowed

"; $tester = new AskApache_Net; $aa_PP['mod_alias_support'] = $atest = ($tester->sockit("{$test_url_base}modaliastest") == 305) ? 1 : 0; echo "

"; echo($atest) ? $aok : $warn; echo " mod_alias detection

"; $tester = new AskApache_Net; $aa_PP['mod_rewrite_support'] = $atest = ($tester->sockit("{$test_url_base}test.gif?modrewritetest=1") == 307) ? 1 : 0; echo "

"; echo($atest) ? $aok : $warn; echo " mod_rewrite detection

"; $tester = new AskApache_Net; $aa_PP['mod_security_support'] = $atest = ($tester->sockit("{$test_url_base}test.gif?modsecuritytest") == 503) ? 1 : 0; echo "

"; echo($atest) ? $aok : $warn; echo " mod_security detection

"; $tester = new AskApache_Net; $aa_PP['mod_auth_digest_support'] = $atest = ($tester->sockit("{$test_url_base}digest_check.gif") == 200) ? 1 : 0; echo "

"; echo($atest) ? $aok : $warn; echo " mod_auth_digest detection

"; echo "

HTTP Digest Authentication

"; ?>

Now we know the encryption and apache module capabilities of your site. This test literally logs in to your server using Digest Authenticationts, providing the ultimate answer as to if your server supports this scheme.

"; echo($atest) ? $aok : $fail; echo " Creating digest htpasswd test file"; $tester = new AskApache_Net; $tester->authtype = ''; $tester->sockit(str_replace('://', '://testDIGEST:testDIGEST@', $test_url_base) . 'digest_auth_test.gif'); $tester->authtype = 'Digest'; $rg = ($tester->sockit(str_replace('://', '://testDIGEST:testDIGEST@', $test_url_base) . 'digest_auth_test.gif') == 200) ? 1 : 0; $tester = new AskApache_Net; $rb = ($tester->sockit($test_url_base . 'digest_auth_test.gif') == 401) ? 1 : 0; $aa_PP['digest_support'] = $atest = ($rb && $rg) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " Digest Authentication Attempt

"; } else echo "

" . $fail . " Major bummer... you don't have mod_auth_digest! (included in apache since 1.1)

"; echo "

Basic Authentication Encryption Algorithms

"; ?>

Basic Authentication uses the .htpasswd file to store your encrypted password. These checks perform actual logins to your server using a different .htpasswd encryption each time.

"; echo($atest) ? $aok : $fail; echo " Creating basic htpasswd test file"; $tester = new AskApache_Net; $rb = ($tester->sockit($test_url_base . 'basic_auth_test.gif') == 401) ? 1 : 0; if ($aa_PP['crypt_support'] != 0) { $tester = new AskApache_Net; $rg = ($tester->sockit(str_replace('://', '://testCRYPT:testCRYPT@', $test_url_base) . 'basic_auth_test.gif') == 200) ? 1 : 0; $aa_PP['crypt_support'] = $atest = ($rb && $rg) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " Basic Authentication Attempt using Crypt Encryption

"; } if ($aa_PP['md5_support'] != 0) { $tester = new AskApache_Net; $rg = ($tester->sockit(str_replace('://', '://testMD5:testMD5@', $test_url_base) . 'basic_auth_test.gif') == 200) ? 1 : 0; $aa_PP['md5_support'] = $atest = ($rb && $rg) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " Basic Authentication Attempt using MD5 Encryption

"; } if ($aa_PP['sha1_support'] != 0) { $tester = new AskApache_Net; $rg = ($tester->sockit(str_replace('://', '://testSHA1:testSHA1@', $test_url_base) . 'basic_auth_test.gif') == 200) ? 1 : 0; $aa_PP['sha1_support'] = $atest = ($rb && $rg) ? 1 : 0; echo "

"; echo($atest) ? $aok : $fail; echo " Basic Authentication Attempt using SHA1 Encryption

"; } $aa_PP['basic_support'] = $atest = ($aa_PP['sha1_support'] != 0 || $aa_PP['md5_support'] != 0 || $aa_PP['crypt_support'] != 0) ? 1 : 0; echo "

"; echo($atest) ? $aok : $warn; echo " Basic Authentication Access Scheme Supported

"; echo "

PHP.ini Information

"; ?>

Some information about your php.ini settings. The following settings may need to be tweaked. Likely they are fine.

"; echo(empty($open_basedir)) ? $aok : $info; echo " open_basedir on/off {$open_basedir}"; $safe_mode = @ini_get('safe_mode'); echo "

"; echo(empty($safe_mode)) ? $aok : $warn; echo " safe_mode on/off {$safe_mode}

"; $disabled_functions = @ini_get('disable_functions'); echo "

"; echo(empty($disabled_functions)) ? $aok : $warn; echo " disable_functions {$disabled_functions}

"; update_option('askapache_password_protect', $aa_PP); echo '
'; if (!$htaccess_test1 || !$htaccess_test2 || !$netok || $aa_PP['htaccess_support'] != 1) { echo '

Im very sorry, but unless you can resolve the failed requirements above you cannot utilize this plugin at this time. :(

'; echo '

Change the AA_PP_DEBUG to true in the source code of this plugin for verbose reasons why these tests failed.

'; echo ''; echo '

'; } else { echo ''; echo '

'; } echo '



'; echo '
'; } /** * aa_pp_setup_options() * * @return */ function aa_pp_setup_options() { add_filter('plugin_action_links', 'aa_pp_plugin_settings', 10, 2); add_options_page(__('AskApache Password Protection', 'askapache-password-protection'), __('AA PassPro', 'askapache-password-protection'), 8, basename(__FILE__), 'aa_pp_main_page'); } /** * aa_pp_plugin_settings() * * @param mixed $links * @param mixed $file * @return */ function aa_pp_plugin_settings($links, $file) { static $this_plugin; if (!$this_plugin) $this_plugin = plugin_basename(__FILE__); if ($file == $this_plugin) $links = array_merge(array('Settings'), $links); return $links; } /** * aa_pp_deactivate() * * @return */ function aa_pp_deactivate() { global $aa_PP, $aa_SIDS; $aa_PP = get_option('askapache_password_protect'); $aa_SIDS = get_option('askapache_password_protect_sids'); $sids = array_keys($aa_SIDS); foreach ($sids as $sid) { aa_pp_deactivate_sid($sid); } $test_files = array('.htaccess', '.htpasswda1', '.htpasswda2', 'basic_auth_test.gif', 'digest_auth_test.gif', 'test.gif', 'digest_check.gif'); foreach ($test_files as $f) aa_pp_unlink($aa_PP['test_dir'] . '/' . $f); @rmdir($aa_PP['test_dir']); delete_option('askapache_password_protect'); delete_option('askapache_password_protect_sids'); } /** * aa_pp_activate() * * @return */ function aa_pp_activate() { global $aa_PP, $aa_SIDS; $aa_PP = $s = $aa_SIDS = array(); $oldoptions = array('aa_home_folder', 'aa_wpadmin_folder', 'aa_htpasswd_file', 'aa_htaccess_file', 'aa_original_htpasswd', 'aa_original_htaccess', 'aa_plugin_message', 'aa_plugin_version', 'aa_home', 'aa_wpadmin', 'aa_htpasswd_f', 'aa_htaccess_f', 'aa_user', 'aa_plugin_message', 'aa_home_folder', 'aa_wpadmin_folder', 'aa_htpasswd_file', 'aa_htaccess_file', 'aa_original_htpasswd', 'aa_original_htaccess', 'aa_plugin_message', 'aa_plugin_version', 'aa_pp_docroot_htaccess', 'aa_pp_wp_includes_htaccess', 'aa_pp_wp_content_htaccess', 'aa_pp_wp_includes_htaccess', 'aa_pp_main_base64', 'aa_pp_ok'); foreach ($oldoptions as $option) delete_option($option); $home = get_option('siteurl'); $su = parse_url($home); $path = (!isset($su['path']) || empty($su['path'])) ? '/' : rtrim($su['path'], '/') . '/'; $scheme = (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' && $su['scheme'] == 'https') ? 'https' : 'http'; $home_path = rtrim(get_home_path(), '/') . '/'; $hu = str_replace($scheme . '://', '', $home); $url = $scheme . '://' . rtrim(str_replace($path, '', $hu), '/'); $authdomain = "{$path}wp-admin/ {$url}{$path}wp-admin/"; update_option('askapache_password_protect', array('step' => 'welcome', 'plugin_data' => get_plugin_data(__FILE__), 'scheme' => $scheme, 'host' => $su['host'], 'root_path' => $path, 'home_path' => $home_path, 'test_dir' => $home_path . 'wp-content/askapache', 'root_htaccess' => $home_path . '.htaccess', 'admin_htaccess' => $home_path . 'wp-admin/.htaccess', 'authdomain' => $authdomain, 'authname' => 'Protected By AskApache', 'user' => '', 'authtype' => '', 'authuserfile' => $home_path . '.htpasswd', 'algorithm' => '', 'htaccess_support' => 0, 'mod_alias_support' => 0, 'mod_rewrite_support' => 0, 'mod_security_support' => 0, 'mod_auth_digest_support' => 0, 'basic_support' => 0, 'digest_support' => 0, 'crypt_support' => 0, 'sha1_support' => 0, 'md5_support' => 0,)); update_option('askapache_password_protect_sids',array( 700000 => array( 'Type'=>'General', 'Version'=>'1.0', 'Name'=>'Directory Protection', 'Description'=>'Enable the DirectoryIndex Protection, preventing directory index listings and defaulting.', 'Rules'=> 'Options -Indexes'."\n". 'DirectoryIndex index.html index.php %relative_root%index.php'), 1012000 => array('Type'=>'Protection', 'Version'=>'1.0', 'Name'=>'Stop Hotlinking', 'Description'=>'Denies any request for static files (images, css, etc) if referrer is not local site or empty.', 'Rules'=> 'RewriteCond %{HTTP_REFERER} !^$'."\n". 'RewriteCond %{REQUEST_URI} !^%relative_root%(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]'."\n". 'RewriteCond %{HTTP_REFERER} !^%scheme%://%host%.*$ [NC]'."\n". 'RewriteRule \.(ico|pdf|flv|jpg|jpeg|mp3|mpg|mp4|mov|wav|wmv|png|gif|swf|css|js)$ - [F,NS,L]'), 800000 => array('Type'=>'Password', 'Version'=>'1.3', 'Name'=>'Password Protect wp-login.php', 'Description'=>'Requires a valid user/pass to access the login page..', 'Rules'=> ''."\n". 'Order Deny,Allow'."\n". 'Deny from All'."\n". 'Satisfy Any'."\n". '%generate_auth%'."\n". ''), 900000 => array('Type'=>'Password', 'Version'=>'1.2', 'Name'=>'Password Protect wp-admin', 'Description'=>'Requires a valid user/pass to access any non-static (css, js, images) file in this directory...', 'Rules'=> 'Order Deny,Allow'."\n". 'Deny from All'."\n". 'Satisfy Any'."\n\n". '%generate_auth%'."\n\n". ''."\n". 'Allow from All'."\n". ''."\n\n". ''."\n\n". ''."\n". 'SecFilterEngine Off'."\n". ''."\n\n". 'Allow from All'."\n". ''), 1017000 => array('Type'=>'Anti-Spam', 'Version'=>'1.0', 'Name'=>'Forbid Proxies', 'Description'=>'Denies POST Request using a Proxy Server. Can access site, but not comment. See Perishable Press', 'Rules'=> 'RewriteCond %{HTTP:VIA}%{HTTP:FORWARDED}%{HTTP:USERAGENT_VIA}%{HTTP:X_FORWARDED_FOR}%{HTTP:PROXY_CONNECTION} !^$ [OR]'."\n". 'RewriteCond %{HTTP:XPROXY_CONNECTION}%{HTTP:HTTP_PC_REMOTE_ADDR}%{HTTP:HTTP_CLIENT_IP} !^$'."\n". 'RewriteCond %{REQUEST_URI} !^%relative_root%(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]'."\n". 'RewriteCond %{REQUEST_METHOD} =POST'."\n". 'RewriteRule .* - [F,NS,L]'), 1018000 => array('Type'=>'Anti-Spam', 'Version'=>'1.0', 'Name'=>'Real wp-comments-post.php', 'Description'=>'Denies any POST attempt made to a non-existing wp-comments-post.php..', 'Rules'=> 'RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ %relative_root%.*/wp-comments-post\.php.*\ HTTP/ [NC]'."\n". 'RewriteRule .* - [F,NS,L]'), 1021000 => array('Type'=>'Anti-Spam', 'Version'=>'1.0', 'Name'=>'BAD Content Length', 'Description'=>'Denies any POST request that doesnt have a Content-Length Header..', 'Rules'=> 'RewriteCond %{REQUEST_METHOD} =POST'."\n". 'RewriteCond %{REQUEST_URI} !^%relative_root%(wp-admin/|wp-content/plugins/|wp-includes/).* [NC]'."\n". 'RewriteCond %{HTTP:Content-Length} ^$'."\n". 'RewriteRule .* - [F,NS,L]'), 1022000 => array('Type'=>'Anti-Spam', 'Version'=>'1.0', 'Name'=>'BAD Content Type', 'Description'=>'Denies any POST request with a content type other than application/x-www-form-urlencoded|multipart/form-data..', 'Rules'=> 'RewriteCond %{REQUEST_METHOD} =POST'."\n". 'RewriteCond %{REQUEST_URI} !^%relative_root%(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]'."\n". 'RewriteCond %{HTTP:Content-Type} !^(application/x-www-form-urlencoded|multipart/form-data.*(boundary.*)?)$ [NC]'."\n". 'RewriteRule .* - [F,NS,L]'), 1025000 => array('Type'=>'Anti-Spam', 'Version'=>'1.0', 'Name'=>'NO HOST:', 'Description'=>'Denies requests that dont contain a HTTP HOST Header...', 'Rules'=> 'RewriteCond %{REQUEST_URI} !^%relative_root%(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]'."\n". 'RewriteCond %{HTTP_HOST} ^$'."\n". 'RewriteRule .* - [F,NS,L]'), 1027000 => array('Type'=>'Anti-Spam', 'Version'=>'1.0', 'Name'=>'No UserAgent, No Post', 'Description'=>'Denies POST requests by blank user-agents. May prevent a small number of visitors from POSTING.', 'Rules'=> 'RewriteCond %{REQUEST_METHOD} =POST'."\n". 'RewriteCond %{REQUEST_URI} !^%relative_root%(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]'."\n". 'RewriteCond %{HTTP_USER_AGENT} ^-?$'."\n". 'RewriteRule .* - [F,NS,L]'), 1028000 => array('Type'=>'Anti-Spam', 'Version'=>'1.0', 'Name'=>'No Referer, No Comment', 'Description'=>'Denies any comment attempt with a blank HTTP_REFERER field, highly indicative of spam. May prevent some visitors from POSTING.', 'Rules'=> 'RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*/wp-comments-post\.php.*\ HTTP/ [NC]'."\n". 'RewriteCond %{HTTP_REFERER} ^-?$'."\n". 'RewriteRule .* - [F,NS,L]'), 1029000 => array('Type'=>'Anti-Spam', 'Version'=>'1.0', 'Name'=>'Trackback Spam', 'Description'=>'Denies obvious trackback spam. See Holy Shmoly!', 'Rules'=> 'RewriteCond %{HTTP_USER_AGENT} ^.*(opera|mozilla|firefox|msie|safari).*$ [NC,OR]'."\n". 'RewriteCond %{HTTP_USER_AGENT} ^-?$'."\n". 'RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.+/trackback/?\ HTTP/ [NC]'."\n". 'RewriteCond %{REQUEST_METHOD} =POST'."\n". 'RewriteRule .* - [F,NS,L]'), 1000000 => array('Type'=>'Exploits', 'Version'=>'1.2', 'Name'=>'Protect wp-content', 'Description'=>'Denies any Direct request for files ending in .php with a 403 Forbidden.. May break plugins/themes', 'Rules'=> 'RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ %relative_root%wp-content/.*$ [NC]'."\n". 'RewriteCond %{REQUEST_FILENAME} !^.+(flexible-upload-wp25js|media)\.php$'."\n". 'RewriteCond %{REQUEST_FILENAME} ^.+\.(php|html|htm|txt)$'."\n". 'RewriteRule .* - [F,NS,L]'), 1010000 => array('Type'=>'Exploits', 'Version'=>'1.2', 'Name'=>'Protect wp-includes', 'Description'=>'Denies any Direct request for files ending in .php with a 403 Forbidden.. May break plugins/themes', 'Rules'=> 'RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ %relative_root%wp-includes/.*$ [NC]'."\n". 'RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ %relative_root%wp-includes/js/.+/.+\ HTTP/ [NC]'."\n". 'RewriteCond %{REQUEST_FILENAME} ^.+\.php$'."\n". 'RewriteRule .* - [F,NS,L]'), 1011000 => array('Type'=>'Exploits', 'Version'=>'1.0', 'Name'=>'Common Exploits', 'Description'=>'Block common exploit requests with 403 Forbidden. These can help alot, may break some plugins.', 'Rules'=> 'RewriteCond %{REQUEST_URI} !^%relative_root%(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]'."\n". 'RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ ///.*\ HTTP/ [NC,OR]'."\n". 'RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.+\?\=?(http|ftp|ssl|https):/.*\ HTTP/ [NC,OR]'."\n". 'RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\?\?.*\ HTTP/ [NC,OR]'."\n". 'RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.(asp|ini|dll).*\ HTTP/ [NC,OR]'."\n". 'RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.(htpasswd|htaccess|aahtpasswd).*\ HTTP/ [NC]'."\n". 'RewriteRule .* - [F,NS,L]'), 1015000 => array('Type'=>'Exploits', 'Version'=>'1.0', 'Name'=>'Safe Request Methods', 'Description'=>'Denies any request not using GET,PROPFIND,POST,OPTIONS,PUT,HEAD..', 'Rules'=> 'RewriteCond %{REQUEST_METHOD} !^(GET|HEAD|POST|PROPFIND|OPTIONS|PUT)$ [NC]'."\n". 'RewriteRule .* - [F,NS,L]'), 1019000 => array('Type'=>'Exploits', 'Version'=>'1.0', 'Name'=>'HTTP PROTOCOL', 'Description'=>'Denies any badly formed HTTP PROTOCOL in the request, 0.9, 1.0, and 1.1 only..', 'Rules'=> 'RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ .+\ HTTP/(0\.9|1\.0|1\.1) [NC]'."\n". 'RewriteRule .* - [F,NS,L]'), 1020000 => array('Type'=>'Exploits', 'Version'=>'1.0', 'Name'=>'SPECIFIC CHARACTERS', 'Description'=>'Denies any request for a url containing characters other than "a-zA-Z0-9.+/-?=&" - REALLY helps but may break your site depending on your links.', 'Rules'=> 'RewriteCond %{REQUEST_URI} !^%relative_root%(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]'."\n". 'RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ [A-Z0-9\.\+_/\-\?\=\&\%\#]+\ HTTP/ [NC]'."\n". 'RewriteRule .* - [F,NS,L]'), 1023000 => array('Type'=>'Exploits', 'Version'=>'1.0', 'Name'=>'Directory Traversal', 'Description'=>'Denies Requests containing ../ or ./. which is a directory traversal exploit attempt..', 'Rules'=> 'RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ .*([\.]+[\.]+).*\ HTTP/ [NC]'."\n". 'RewriteRule .* - [F,NS,L]'), 1024000 => array('Type'=>'Exploits', 'Version'=>'1.0', 'Name'=>'PHPSESSID Cookie', 'Description'=>'Only blocks when a PHPSESSID cookie is sent by the user and it contains characters other than 0-9a-z..', 'Rules'=> 'RewriteCond %{HTTP_COOKIE} ^.*PHPSESS?ID.*$'."\n". 'RewriteCond %{HTTP_COOKIE} !^.*PHPSESS?ID=([0-9a-z]+);.*$'."\n". 'RewriteRule .* - [F,NS,L]'), 1026000 => array('Type'=>'Exploits', 'Version'=>'1.0', 'Name'=>'Bogus Graphics Exploit', 'Description'=>'Denies obvious exploit using bogus graphics..', 'Rules'=> 'RewriteCond %{HTTP:Content-Disposition} \.php [NC]'."\n". 'RewriteCond %{HTTP:Content-Type} image/.+ [NC]'."\n". 'RewriteRule .* - [F,NS,L]') ) ); } /** * aa_pp_debug() * * @param string $message * @return */ function aa_pp_debug($message = '') { @error_log(ltrim("PHP AA Error: {$message}")); return false; } /** * aa_pp_notify() * * @param string $message * @return */ function aa_pp_notify($message = '') { error_log("PHP AA Info: {$message}"); } if (!class_exists("AskApache_Net")) { /** * AskApache_Net * * @package * @author AskApache * @copyright Copyright (c) 2008 * @version $Id$ * @access public */ class AskApache_Net { var $socket = array('protocol' => '1.0', 'method' => 'GET', 'ua' => 'Mozilla/5.0 (compatible; AskApache_Net/1.0; http://www.askapache.com)', 'referer' => 'http://www.askapache.com', 'port' => '80', 'url' => '', 'scheme' => '', 'host' => '', 'ip' => '', 'user' => '', 'pass' => '', 'path' => '', 'query' => '', 'fragment' => ''); var $digests = array('realm' => '', 'nonce' => '', 'uri' => '', 'algorithm' => 'MD5', 'qop' => 'auth', 'opaque' => '', 'domain' => '', 'nc' => '00000001', 'cnonce' => '82d057852a9dc497', 'A1' => '', 'A2' => '', 'response' => ''); var $dh = ''; var $authtype = 'Basic'; var $error = ''; var $request = ''; var $request_headers = array(); var $response = ''; var $response_headers = array(); var $response_code = ''; var $time_start = null; var $redo_digest = false; var $did_digest = false; var $_fp = null; var $_speed = 24576; var $_chunks = 256; var $_maxlength = 4096; var $_fp_timeout = 10; var $_read_timeout = 45; /** * AskApache_Net::sockit() * * @param mixed $URI * @return */ function sockit($URI) { if (AA_PP_DEBUG) error_log($URI); if (!$this->_build_sock($URI)) return false; if (!$this->_connect()) return false; if (!$this->_build_request()) return false; if (!$this->_set_sock_time()) echo "Failed setting socket timeout, not a big deal."; $this->set_speed(24); if (!$this->_tx()) return false; $this->_rx(); $this->get_response_code(); $this->_disconnect(); if (AA_PP_DEBUG) { echo '
';
                print_r($this->request_headers);
                print_r($this->response_headers);
                echo '
'; } return(int)$this->response_code; } /** * AskApache_Net::get_response_code() * * @return */ function get_response_code() { $status = null; preg_match('/HTTP.*([0-9]{3}).*/', $this->response_headers[0], $status); $this->response_code = $status[1]; return $this->response_code; } /** * AskApache_Net::get_response_headers() * * @return */ function get_response_headers() { return $this->response_headers; } /** * AskApache_Net::get_response_body() * * @return */ function get_response_body() { return $this->response; } /** * AskApache_Net::set_speed() * * @param mixed $speed * @return */ function set_speed($speed) { $this->_speed = round($speed * 1024); } /** * AskApache_Net::_connect() * * @return */ function _connect() { $fp = null; if (false === ($fp = @fsockopen($this->socket['ip'], $this->socket['port'], $errno, $errstr, $this->_fp_timeout)) || !is_resource($fp)) { switch ($errno) { case - 3: $err = "Socket creation failed"; break; case - 4: $err = "DNS lookup failure"; break; case - 5: $err = "Connection refused or timed out"; break; case 111: $err = "Connection refused"; break; case 113: $err = "No route to host"; break; case 110: $err = "Connection timed out"; break; case 104: $err = "Connection reset by client"; break; default: $err = "Connection failed"; break; } echo "Fsockopen failed! [{$errno}] {$err} ({$errstr})"; return false; } $this->_fp = $fp; return true; } /** * AskApache_Net::_disconnect() * * @return */ function _disconnect() { return(@fclose($this->_fp)); } /** * AskApache_Net::_rx() * * @return */ function _rx() { $buf = $response = ''; while (!feof($this->_fp) && $buf = @fread($this->_fp, $this->_speed)) { $response .= $buf; sleep(1); } $g = strpos($response, ACLF . ACLF); $headers = substr($response, 0, $g); $this->response = substr($response, $g, (strlen($response) - $g)); $this->response_headers = explode(ACLF, $headers); } /** * AskApache_Net::_tx() * * @param mixed $request * @return */ function _tx($request = null) { $g = false; $g = (!is_null($request)) ? @fwrite($this->_fp, $request, strlen($request)) : @fwrite($this->_fp, $this->request, strlen($this->request)); return(bool)$g; } /** * AskApache_Net::_build_sock() * * @param mixed $url * @return */ function _build_sock($url) { if (!$u_bits = parse_url($url)) return false; if (AA_PP_DEBUG) { echo '
';
                print_r($u_bits);
                echo '
'; } if (empty($u_bits['url'])) $u_bits['url'] = (!empty($this->socket['url'])) ? $this->socket['url'] : 'url'; if (empty($u_bits['method'])) $u_bits['method'] = (!empty($this->socket['method'])) ? $this->socket['method'] : 'GET'; if (empty($u_bits['protocol'])) $u_bits['protocol'] = (!empty($this->socket['protocol'])) ? $this->socket['protocol'] : '1.0'; if (empty($u_bits['host'])) $u_bits['host'] = (!empty($this->socket['host'])) ? $this->socket['host'] : $_SERVER['HTTP_HOST']; if (empty($u_bits['ip'])) $u_bits['ip'] = (!empty($this->socket['ip'])) ? $this->socket['ip'] : $this->_get_ip($u_bits['host']); if (empty($u_bits['scheme'])) $u_bits['scheme'] = (!empty($this->socket['scheme'])) ? $this->socket['scheme'] : 'http'; if (empty($u_bits['port'])) $u_bits['port'] = (!empty($this->socket['port'])) ? $this->socket['port'] : $_SERVER['SERVER_PORT']; if (empty($u_bits['path'])) $u_bits['path'] = (!empty($this->socket['path'])) ? $this->socket['path'] : '/'; if (empty($u_bits['ua'])) $u_bits['ua'] = (!empty($this->socket['ua'])) ? $this->socket['ua'] : 'Mozilla/5.0 (compatible; AskApache_Net/1.0; http://www.askapache.com)'; if (empty($u_bits['referer'])) $u_bits['referer'] = (!empty($this->socket['referer'])) ? $this->socket['referer'] : 'http://www.askapache.com'; if (!empty($u_bits['user'])) $this->socket['user'] = $u_bits['user']; else $u_bits['user'] = (!empty($this->socket['user'])) ? $this->socket['user'] : ''; if (!empty($u_bits['pass'])) $this->socket['pass'] = $u_bits['pass']; else $u_bits['pass'] = (!empty($this->socket['pass'])) ? $this->socket['pass'] : ''; if (empty($u_bits['fragment'])) $u_bits['fragment'] = (!empty($this->socket['fragment'])) ? $this->socket['fragment'] : ''; if (!empty($u_bits['query'])) $u_bits['path'] .= '?' . $u_bits['query']; else $u_bits['path'] .= (!empty($this->socket['query'])) ? '?' . $this->socket['query'] : ''; if (AA_PP_DEBUG) { echo '
';
                print_r($u_bits);
                echo '
'; } $this->socket = $u_bits; return true; } /** * AskApache_Net::_build_request() * * @return */ function _build_request() { $_request_headers = array(); $_request_headers[] = $this->socket['method'] . " " . $this->socket['path'] . " HTTP/" . $this->socket['protocol']; $_request_headers[] = "Host: " . $this->socket['host']; $_request_headers[] = "User-Agent: " . $this->socket['ua']; $_request_headers[] = 'Accept: application/xhtml+xml,text/html;q=0.9,*/*;q=0.5'; $_request_headers[] = 'Accept-Language: en-us,en;q=0.5'; $_request_headers[] = 'Accept-Encoding: none'; $_request_headers[] = 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7'; $_request_headers[] = 'Referer: ' . $this->socket['referer']; if (!empty($this->socket['user']) && !empty($this->socket['pass'])) { if ($this->authtype == 'Basic') $_request_headers[] = 'Authorization: Basic ' . base64_encode($this->socket['user'] . ":" . $this->socket['pass']); elseif ($this->authtype == 'Digest') $_request_headers[] = $this->getdigest(); } $this->request_headers = $_request_headers; $this->request = join(ACLF, $_request_headers) . ACLF . ACLF; return true; } /** * AskApache_Net::_get_ip() * * @param mixed $host * @return */ function _get_ip($host) { $hostip = @gethostbyname($host); $ip = ($hostip == $host) ? $host : long2ip(ip2long($hostip)); return $ip; } /** * AskApache_Net::_set_sock_time() * * @return */ function _set_sock_time() { @ini_set("default_socket_timeout", $this->_read_timeout); if (function_exists("socket_set_timeout")) @socket_set_timeout($this->_fp, $this->_read_timeout); elseif (function_exists("stream_set_timeout")) @stream_set_timeout($this->_fp, $this->_read_timeout); return true; } /** * AskApache_Net::getdigest() * * @return */ function getdigest() { foreach ($this->response_headers as $num => $header) { if (preg_match('/WWW-Authenticate: Digest/i', $header)) $this->dh = $dh = substr($header, 25); } $dh = $this->dh; $this->socket['protocol'] = '1.1'; $mydigest = $this->digests; if (preg_match('/realm="([^"]*?)"/i', $dh, $match)) { if (isset($match[1]) && !empty($match[1])) $mydigest['realm'] = $match[1]; } if (preg_match('/nonce="([^"]*?)"/i', $dh, $match)) { if (isset($match[1]) && !empty($match[1])) $mydigest['nonce'] = $match[1]; } if (preg_match('/cnonce="([^"]*?)"/i', $dh, $match)) { if (isset($match[1]) && !empty($match[1])) $mydigest['cnonce'] = $match[1]; } if (preg_match('/algorithm=(MD5|MD5-sess),/i', $dh, $match)) { if (isset($match[1]) && !empty($match[1])) $mydigest['algorithm'] = $match[1]; } if (preg_match('/domain="([^"]*?)"/i', $dh, $match)) { if (isset($match[1]) && !empty($match[1])) $mydigest['domain'] = $match[1]; } if (preg_match('/opaque="([^"]*?)"/i', $dh, $match)) { if (isset($match[1]) && !empty($match[1])) $mydigest['opaque'] = $match[1]; } if (preg_match('/qop=[\'\"]?(auth|auth-int)[\'\"]?/i', $dh, $match)) { if (isset($match[1]) && !empty($match[1])) $mydigest['qop'] = $match[1]; } if (preg_match('/nc=([0-9]*?)/i', $dh, $match)) { if (isset($match[1]) && !empty($match[1])) $mydigest['nc'] = $match[1]; } $mydigest['uri'] = $this->socket['path']; $mydigest['A1'] = md5($this->socket['user'] . ':' . $mydigest['realm'] . ':' . $this->socket['pass']); $mydigest['A2'] = md5($this->socket['method'] . ':' . $this->socket['path']); $mydigest['response'] = md5($mydigest['A1'] . ':' . $mydigest['nonce'] . ':' . $mydigest['nc'] . ':' . $mydigest['cnonce'] . ':' . $mydigest['qop'] . ':' . $mydigest['A2']); $this->digests = $mydigest; $ah = 'Authorization: Digest username="' . $this->socket['user'] . '", realm="' . $mydigest['realm'] . '", nonce="' . $mydigest['nonce'] . '", uri="' . $mydigest['uri'] . '"'; $ah .= ', algorithm=' . $mydigest['algorithm'] . ', response="' . $mydigest['response'] . '"'; $ah .= ', qop=' . $mydigest['qop'] . ', nc=' . $mydigest['nc']; if (!empty($mydigest['cnonce'])) $ah .= ', cnonce="' . $mydigest['cnonce'] . '"'; if (!empty($mydigest['opaque'])) $ah .= ', opaque="' . $mydigest['opaque'] . '"'; if (AA_PP_DEBUG) { echo '
';
                echo $ah . "\n";
                print_r($mydigest);
                echo '
'; } return $ah; } } } ?>