Attachment 'http-authentication.php'

Download

   1 <?php
   2 /*
   3 Plugin Name: HTTP Authentication
   4 Version: 2.2
   5 Plugin URI: http://dev.webadmin.ufl.edu/~dwc/2008/04/16/http-authentication-20/
   6 Description: Authenticate users using basic HTTP authentication (<code>REMOTE_USER</code>). This plugin assumes users are externally authenticated, as with <a href="http://www.gatorlink.ufl.edu/">GatorLink</a>.
   7 Author: Daniel Westermann-Clark
   8 Author URI: http://dev.webadmin.ufl.edu/~dwc/
   9 */
  10 
  11 if (! class_exists('HTTPAuthenticationPlugin')) {
  12 	class HTTPAuthenticationPlugin {
  13 		function HTTPAuthenticationPlugin() {
  14 			register_activation_hook(__FILE__, array(&$this, 'initialize_options'));
  15 
  16 			add_action('admin_menu', array(&$this, 'add_options_page'));
  17 			add_action('wp_authenticate', array(&$this, 'authenticate'), 10, 2);
  18 			add_filter('check_password', array(&$this, 'skip_password_check'), 10, 4);
  19 			add_filter('user_registration_email', array(&$this, 'user_registration_email'));
  20 			add_action('user_register', array(&$this, 'user_register'));
  21 			add_action('set_current_user', array(&$this, 'set_current_user'));
  22 			add_action('wp_logout', array(&$this, 'logout'));
  23 			add_action('lost_password', array(&$this, 'disable_function'));
  24 			add_action('retrieve_password', array(&$this, 'disable_function'));
  25 			add_action('password_reset', array(&$this, 'disable_function'));
  26 			add_action('check_passwords', array(&$this, 'generate_password'), 10, 3);
  27 			add_filter('show_password_fields', array(&$this, 'disable_password_fields'));
  28 		}
  29 
  30 
  31 		/*************************************************************
  32 		 * Plugin hooks
  33 		 *************************************************************/
  34 
  35 		/*
  36 		 * Add options for this plugin to the database.
  37 		 */
  38 		function initialize_options() {
  39 			if (current_user_can('manage_options')) {
  40 				add_option('http_authentication_logout_uri', get_option('home'), 'The URI to which the user is redirected when she chooses "Logout".');
  41 				add_option('http_authentication_auto_create_user', false, 'Should a new user be created automatically if not already in the WordPress database?');
  42 				add_option('http_authentication_auto_create_email_domain', '', 'The domain to use for the email address of an automatically created user.');
  43 			}
  44 		}
  45 
  46 		/*
  47 		 * Add an options pane for this plugin.
  48 		 */
  49 		function add_options_page() {
  50 			if (function_exists('add_options_page')) {
  51 				add_options_page('HTTP Authentication', 'HTTP Authentication', 9, __FILE__, array(&$this, '_display_options_page'));
  52 			}
  53 		}
  54 
  55 		function get_emails() {
  56 			$emails[] = $_SERVER['SSL_CLIENT_S_DN_EMAIL'];
  57 
  58 			$d=0;
  59 			while ($emails[] = $_SERVER["SSL_CLIENT_S_DN_EMAIL_$d"]) {
  60        				++$d;
  61 			}
  62 
  63 			$dn=$_SERVER['SSL_CLIENT_S_DN'];
  64 			# match on the following DN
  65 			# emailAddress= (current cacert issued ones 20090402) https://bugs.cacert.org/view.php?id=672
  66 			if (preg_match_all('/\/emailAddress=([^\/]*)/',$dn,$reg,PREG_SET_ORDER)) {
  67 				foreach ($reg as $emailarr) {
  68 					$emails[] = $emailarr[1];
  69 				}
  70 			}
  71 
  72 			if ( $_SERVER['SSL_CLIENT_CERT']) {
  73 				# subjectAltName unpresented by Apache http://httpd.apache.org/docs/trunk/mod/mod_ssl.html
  74 				# subjectAltName http://tools.ietf.org/html/rfc5280#section-4.2.1.6
  75 				# WARNING WARNING openssl_x509_parse is an unstable PHP API
  76 
  77 				$x509 = openssl_x509_parse($_SERVER['SSL_CLIENT_CERT']);
  78 				$subjectAltName = $x509['extensions']['subjectAltName']; // going off https://foaf.me/testSSL.php
  79 				if (preg_match_all('/email:([^, ]*)/',$subjectAltName,$reg,PREG_SET_ORDER)) {
  80 					foreach ($reg as $emailarr) {
  81 						$emails[] = $emailarr[1];
  82 					}
  83 				}
  84 			}
  85 			function  _true_fun($x) { return $x; }
  86 
  87 			return array_filter($emails,_true_fun);
  88 		}
  89 
  90 		/*
  91 		 * You can only register with an email that belongs to you
  92 		 */
  93 		function user_registration_email($email) {
  94 			$emails = $this->get_emails();
  95 			if (in_array($email,$emails)) {
  96 				return $email;
  97 			}
  98 			return 'invalidemail';
  99 		}
 100 
 101 		function user_register($id) {
 102 			$user = new WP_User($id);
 103 			if ( $user && $_SERVER['SSL_CLIENT_S_DN_CN'] != 'CAcert WoT Member' ) {
 104 				$user->set_role('author');
 105 			}
 106 		}
 107 
 108 		function set_current_user() {
 109 			require_once(ABSPATH . WPINC . '/capabilities.php');
 110 			if  ( ! current_user_can('publish_posts') && $_SERVER['SSL_CLIENT_S_DN_CN'] != 'CAcert WoT Member' ) {
 111 				$current_user = wp_get_current_user();
 112 				$current_user->set_role('author');
 113 			}	
 114 		}
 115 
 116 		/*
 117 		 * If the email addresses from the certificate exist this is counted as authentication
 118 		 */
 119 		function authenticate($username, $password) {
 120 			$username = '';
 121 			$emails = $this->get_emails();
 122 			foreach ($emails as $email) {
 123 				if( $user = get_user_by_email($email)) {
 124 					break;
 125 				}
 126 			}
 127 
 128 			if (empty($emails)) {
 129 				$url = get_option('siteurl') . '/requirecert/wp-login.php';
 130 				die("No certificate information presented; Safari User please use <a href=\"$url\">this link</a>");
 131 			}
 132 
 133 			// Fake WordPress into authenticating by overriding the credentials
 134 			$password = $this->_get_password();
 135 			$username = $user->user_login;
 136 
 137 			if (! $user or !in_array($user->user_email,$emails)) {
 138 				if ((bool) get_option('http_authentication_auto_create_user')) {
 139 					$username = $this->_create_user(array_shift($emails));
 140 					if (!$username) {
 141 						wp_redirect(get_option('siteurl') . '/wp-login.php?action=register');
 142 					}
 143 				} else {
 144 					// Bail out to avoid showing the login form
 145 					wp_redirect(get_option('siteurl') . '/wp-login.php?action=register');
 146 				}
 147 			}
 148 		}
 149 
 150 		/*
 151 		 * Skip the password check, since we've externally authenticated.
 152 		 */
 153 		function skip_password_check($check, $password, $hash, $user_id) {
 154 			return true;
 155 		}
 156 
 157 		/*
 158 		 * Logout the user by redirecting them to the logout URI.
 159 		 */
 160 		function logout() {
 161 			header('Location: ' . get_option('http_authentication_logout_uri'));
 162 			exit();
 163 		}
 164 
 165 		/*
 166 		 * Generate a password for the user. This plugin does not
 167 		 * require the user to enter this value, but we want to set it
 168 		 * to something nonobvious.
 169 		 */
 170 		function generate_password($username, $password1, $password2) {
 171 			$password1 = $password2 = $this->_get_password();
 172 		}
 173 
 174 		/*
 175 		 * Used to disable certain display elements, e.g. password
 176 		 * fields on profile screen.
 177 		 */
 178 		function disable_password_fields($show_password_fields) {
 179 			return false;
 180 		}
 181 
 182 		/*
 183 		 * Used to disable certain login functions, e.g. retrieving a
 184 		 * user's password.
 185 		 */
 186 		function disable_function() {
 187 			die('Disabled');
 188 		}
 189 
 190 
 191 		/*************************************************************
 192 		 * Functions
 193 		 *************************************************************/
 194 
 195 		/*
 196 		 * Generate a random password.
 197 		 */
 198 		function _get_password($length = 10) {
 199 			return substr(md5(uniqid(microtime())), 0, $length);
 200 		}
 201 
 202 		/*
 203 		 * Create a new WordPress account for the specified username.
 204 		 */
 205 		function _create_user($email) {
 206 			$password = $this->_get_password();
 207 			$username = strtok($email, '@');
 208 			require_once(WPINC . DIRECTORY_SEPARATOR . 'registration.php');
 209 			if (!username_exists($username)) {
 210 				wp_create_user($username, $password, $email);
 211 				return $username;
 212 			} else {
 213 				return null;
 214 			}
 215 		}
 216 
 217 
 218 		/*
 219 		 * Display the options for this plugin.
 220 		 */
 221 		function _display_options_page() {
 222 			$logout_uri = get_option('http_authentication_logout_uri');
 223 			$auto_create_user = (bool) get_option('http_authentication_auto_create_user');
 224 			$auto_create_email_domain = get_option('http_authentication_auto_create_email_domain');
 225 ?>
 226 <div class="wrap">
 227   <h2>HTTP Authentication Options</h2>
 228   <form action="options.php" method="post">
 229     <input type="hidden" name="action" value="update" />
 230     <input type="hidden" name="page_options" value="http_authentication_logout_uri,http_authentication_auto_create_user,http_authentication_auto_create_email_domain" />
 231     <?php if (function_exists('wp_nonce_field')): wp_nonce_field('update-options'); endif; ?>
 232 
 233     <table class="form-table">
 234       <tr valign="top">
 235         <th scope="row"><label for="http_authentication_logout_uri">Logout URI</label></th>
 236         <td>
 237           <input type="text" name="http_authentication_logout_uri" id="http_authentication_logout_uri" value="<?php echo htmlspecialchars($logout_uri) ?>" size="50" /><br />
 238           Default is <code><?php echo htmlspecialchars(get_option('home')); ?></code>; override to e.g. remove a cookie.
 239         </td>
 240       </tr>
 241       <tr valign="top">
 242         <th scope="row"><label for="http_authentication_auto_create_user">Automatically create accounts?</label></th>
 243         <td>
 244           <input type="checkbox" name="http_authentication_auto_create_user" id="http_authentication_auto_create_user"<?php if ($auto_create_user) echo ' checked="checked"' ?> value="1" /><br />
 245           Should a new user be created automatically if not already in the WordPress database?<br />
 246           Created users will obtain the role defined under &quot;New User Default Role&quot; on the <a href="options-general.php">General Options</a> page.
 247         </td>
 248       </tr>
 249       <tr valign="top">
 250         <th scope="row"><label for="http_authentication_auto_create_email_domain">Email address domain</label></th>
 251         <td>
 252           <input type="text" name="http_authentication_auto_create_email_domain" id="http_authentication_auto_create_email_domain" value="<?php echo htmlspecialchars($auto_create_email_domain) ?>" size="50" /><br />
 253           When a new user logs in, this domain is used for the initial email address on their account. The user can change his or her email address by editing their profile.
 254         </td>
 255       </tr>
 256     </table>
 257     <p class="submit">
 258       <input type="submit" name="Submit" value="Save Changes" />
 259     </p>
 260   </form>
 261 </div>
 262 <?php
 263 		}
 264 	}
 265 }
 266 
 267 // Load the plugin hooks, etc.
 268 $http_authentication_plugin = new HTTPAuthenticationPlugin();
 269 ?>

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2013-07-13 22:11:38, 6.5 KB) [[attachment:client-certificate-authentication.zip]]
  • [get | view] (2009-10-03 00:53:00, 9.6 KB) [[attachment:http-authentication.php]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.