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 "New User Default Role" 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.You are not allowed to attach a file to this page.