Semisecure Integration

Semisecure Login Reimagined supports 3rd-party integration. This might be useful if you have a custom plugin/widget that allows you to submit a password to login (or for registration). Information on how the integration works can be found on the plugin’s settings page. Up until now I haven’t seen any complete examples. To fill the gap, here’s a complete example using the Register Plus plugin (which allows you to enter your own password when registering):

(This should only be considered a reference; I’m not supporting the following plugin)

<?php
/*
Plugin Name: SemisecureLoginReimagined-RegisterPlus-Bridge
Plugin URI: http://moggy.laceous.com
Description: Integrate SemisecureLoginReimagined with RegisterPlus (reference implementation; tested with: PHP 5.2.9, WP 2.8.6, SLR 3.0.8.3, RP 3.5.1)
Author: moggy
Author URI: http://moggy.laceous.com
Version: 1.0
*/

// hook into the registration form (wp-login.php?action=register)
// make sure this function runs before RegisterPlus
add_action('register_form', 'slr_rp_b_register_form', -1000);
function slr_rp_b_register_form() {
  // if both plugins are activated (and configured)
  if (slr_rp_b_plugins_activated()) {
    // if there are any errors, RegisterPlus will pass the unencrypted password from the server to the browser
    // this stops the password from being sent in the clear
    if (isset($_POST['pass1']))
      unset($_POST['pass1']);
    if (isset($_POST['pass2']))
      unset($_POST['pass2']);
  }
}

// hook into the head section of the registration page (wp-login.php?action=register)
add_action('login_head', 'slr_rp_b_login_head');
function slr_rp_b_login_head() {
  // if this is the registration page and both plugins are activated (and configured)
  if ($_GET['action'] == 'register' && slr_rp_b_plugins_activated()) {
    // Make sure that all the external JavaScript is available (including jQuery)
    SemisecureLoginReimagined::enqueue_js(true);
    // insert our custom JavaScript
    ?>
    <script type="text/javascript">
    //<![CDATA[
      jQuery(document).ready(function($) {
        // display a default message
        $('#pass2').after('<span id="semisecure-message">Semisecure Login is enabled.</span>');

        // Bind to the form's submit event
        $('form#registerform').submit(function() {
          // update the message when the form is submitted
          $('#semisecure-message').text('Encrypting password & submitting...');

          // Collect the password(s)...
          var pass1 = $('#pass1').val();
          var pass2 = $('#pass2').val();
          var passwords = [];
          passwords[0] = pass1;
          passwords[1] = pass2;

          // ...and form name(s)
          var names = [];
          names[0] = $('#pass1').attr('name');
          names[1] = $('#pass2').attr('name');

          // Pass the needed PHP values over to the JavaScript side
          var public_n = '<?php echo SemisecureLoginReimagined::public_n(); ?>';
          var public_e = '<?php echo SemisecureLoginReimagined::public_e(); ?>';
          var uuid = '<?php echo SemisecureLoginReimagined::uuid(); ?>';
          var nonce_js = '<?php echo SemisecureLoginReimagined::nonce_js(); ?>';
          var max_rand_chars = '<?php echo SemisecureLoginReimagined::max_rand_chars(); ?>';
          var rand_chars = '<?php echo addslashes(SemisecureLoginReimagined::rand_chars()); ?>';
          var secret_key_algo = '<?php echo SemisecureLoginReimagined::secret_key_algo(); ?>';

          // Encrypt the password(s)
          var arr = SemisecureLoginReimagined.encrypt(passwords, names, nonce_js, public_n, public_e, uuid, secret_key_algo, rand_chars, max_rand_chars);

          if (arr) {
            // Loop through the array and append the controls to the form
            for (var i = 0; i < arr.length; i++) {
              $('form#registerform').append(arr[i]);
            }

            // Finally, don't submit the plain-text password(s)
            // One option is to submit asterisks in place of the actual password
            var temp1 = '';
            var temp2 = '';
            for (var i = 0; i < pass1.length; i++) { temp1 += '*'; }
            for (var i = 0; i < pass2.length; i++) { temp2 += '*'; }
            $('#pass1').val(temp1);
            $('#pass2').val(temp2);
            // Another option is to disable the control(s) with the plain-text password(s) altogether
            $('#pass1').attr('disabled', 'true');
            $('#pass2').attr('disabled', 'true');
            return true;
          }
          else {
            $('#semisecure-message').text('Problem encrypting password! Please disable JavaScript to submit without encryption.');
            return false;
          }
        });
      })
    //]]>
    </script>
    <?php
  }
}

function slr_rp_b_plugins_activated() {
  // if SemisecureLoginReimagined v3 is activated (tested w/ v3.0.8.3)
  // Note: v3.0.5 fixed a bug with the version method in this context
  if (method_exists('SemisecureLoginReimagined', 'version') && version_compare(SemisecureLoginReimagined::version(), '3.0', '>=')) {
    // if the RSA keypair has been generated and openssl is available
    if (SemisecureLoginReimagined::is_rsa_key_ok() && SemisecureLoginReimagined::is_openssl_avail()) {
      // if RegisterPlus is activated (tested w/ v3.5.1)
      if (class_exists('RegisterPlusPlugin')) {
        // if registrants can enter their own password
        $regplus = get_option( 'register_plus' );
        if (is_array($regplus) && $regplus['password']) {
          return true;
        }
      }
    }
  }
  return false;
}

?>

Leave a Reply

No Comments

No comments yet, be the first to add one!

Archives