--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/yms/yms.php Fri Jul 31 23:51:08 2009 -0400
@@ -0,0 +1,842 @@
+<?php
+
+function page_Special_YMS()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang;
+ global $output;
+
+ // Require re-auth?
+ if ( $session->auth_level < USER_LEVEL_CHPREF && getConfig('yms_require_reauth', 1) == 1 )
+ {
+ redirect(makeUrlNS('Special', "Login/$paths->fullpage", 'level=' . USER_LEVEL_CHPREF), '', '', 0);
+ }
+
+ // Check for Yubikey plugin
+ if ( !function_exists('yubikey_validate_otp') )
+ {
+ die_friendly($lang->get('yms_err_yubikey_plugin_missing_title'), '<p>' . $lang->get('yms_err_yubikey_plugin_missing_body') . '</p>');
+ }
+
+ // Does the client exist?
+ $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . "yms_clients WHERE id = {$session->user_id};");
+ if ( !$q )
+ $db->_die();
+
+ $client_exists = $db->numrows();
+ $db->free_result();
+ if ( !$client_exists )
+ {
+ redirect(makeUrlNS('Special', 'YMSCreateClient'), '', '', 0);
+ }
+
+ // Check for a subpage request
+ if ( $subpage = $paths->getParam(0) )
+ {
+ if ( preg_match('/^[A-z0-9]+$/', $subpage) )
+ {
+ if ( function_exists("page_Special_YMS_{$subpage}") )
+ {
+ // call the subpage
+ return call_user_func("page_Special_YMS_{$subpage}");
+ }
+ }
+ }
+
+ //
+ // POST processing
+ //
+
+ if ( isset($_POST['add_aes']) && isset($_POST['add_otp']) )
+ {
+ $client_id = false;
+ $enabled = $_POST['state'] == 'active';
+ $any_client = isset($_POST['any_client']);
+ $notes = $_POST['notes'];
+ $result = yms_add_yubikey($_POST['add_aes'], $_POST['add_otp'], $client_id, $enabled, $any_client, $notes);
+ yms_send_response('yms_msg_addkey_success', $result);
+ }
+ else if ( isset($_POST['claim_otp']) )
+ {
+ // do we need to validate a custom field?
+ if ( ($url = getConfig('yms_claim_auth_url')) && getConfig('yms_claim_auth_field') )
+ {
+ if ( ($result = yms_validate_custom_field($_POST['custom_field'], $_POST['claim_otp'], $url)) !== true )
+ yms_send_response('n/a', $result);
+ }
+
+ // validate this OTP, make sure it's all good
+ $result = strtolower(yms_validate_otp($_POST['claim_otp'], 0));
+ if ( $result !== 'ok' )
+ yms_send_response('n/a', "yubiauth_err_response_{$result}");
+
+ // change owner
+ $client_id = false;
+ $enabled = $_POST['state'] == 'active';
+ $any_client = isset($_POST['any_client']);
+ $notes = $_POST['notes'];
+ $result = yms_chown_yubikey($_POST['claim_otp'], $client_id, $enabled, $any_client, $notes);
+ yms_send_response('yms_msg_addkey_success', $result);
+ }
+
+ // Preload JS libraries we need for Yubikey
+ $template->preload_js(array('jquery', 'jquery-ui', 'l10n', 'flyin', 'messagebox', 'fadefilter'));
+ // Load CSS
+ $template->add_header('<link rel="stylesheet" type="text/css" href="' . scriptPath . '/plugins/yms/styles.css" />');
+ // Load JS
+ $template->add_header('<script type="text/javascript" src="' . scriptPath . '/plugins/yms/cp.js"></script>');
+
+ // Send header
+ $output->header();
+
+ // Message container
+ if ( !isset($_GET['ajax'] ) )
+ echo '<div id="yms-messages"></div><div id="yms-keylist">';
+
+ // Buttons
+ ?>
+ <div class="yms-buttons">
+ <a class="abutton abutton_green icon" style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/key_add.png);"
+ href="<?php echo makeUrlNS('Special', 'YMS/AddKey'); ?>" onclick="yms_showpage('AddKey'); return false;">
+ <?php echo $lang->get('yms_btn_add_key'); ?>
+ </a>
+ <a class="abutton abutton_blue icon" style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/key_add.png);"
+ href="<?php echo makeUrlNS('Special', 'YMS/AddPreregisteredKey'); ?>" onclick="yms_showpage('AddPreregisteredKey'); return false;">
+ <?php echo $lang->get('yms_btn_add_key_preregistered'); ?>
+ </a>
+ </div>
+ <?php
+
+ // Pull all Yubikeys
+ $q = $db->sql_query('SELECT id, public_id, session_count, create_time, access_time, flags, notes FROM ' . table_prefix . "yms_yubikeys WHERE client_id = {$session->user_id};");
+ if ( !$q )
+ $db->_die();
+
+ if ( $db->numrows() < 1 )
+ {
+ echo '<h2 class="emptymessage">' . $lang->get('yms_msg_no_yubikeys') . '</h2>';
+ }
+ else
+ {
+ ?>
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+
+ <!-- Table header -->
+ <tr>
+ <th><?php echo $lang->get('yms_th_id'); ?></th>
+ <th><?php echo $lang->get('yms_th_publicid'); ?></th>
+ <th><?php echo $lang->get('yms_th_createtime'); ?></th>
+ <th><?php echo $lang->get('yms_th_accesstime'); ?></th>
+ <th><?php echo $lang->get('yms_th_state'); ?></th>
+ <th><?php echo $lang->get('yms_th_note'); ?></th>
+ <th></th>
+ </tr>
+
+ <?php
+ $cls = 'row2';
+ while ( $row = $db->fetchrow($q) )
+ {
+ $cls = $cls == 'row2' ? 'row1' : 'row2';
+ ?>
+ <tr>
+ <!-- Key ID -->
+ <td style="text-align: center;" class="<?php echo $cls; ?>"><?php echo $row['id']; ?></td>
+
+ <!-- Public UID -->
+ <td style="text-align: left;" class="<?php echo $cls; ?>"><?php echo yms_modhex_encode($row['public_id']); ?></td>
+
+ <!-- Create time -->
+ <td style="text-align: left;" class="<?php echo $cls; ?>"><?php echo yms_date($row['create_time']); ?></td>
+
+ <!-- Access time -->
+ <td style="text-align: left;" class="<?php echo $cls; ?>"><?php echo $row['access_time'] <= $row['create_time'] ? $lang->get('yms_msg_access_never') : yms_date($row['access_time']); ?></td>
+
+ <!-- State -->
+ <td style="text-align: center;" class="<?php echo $cls; ?>"><?php echo yms_state_indicator($row['flags'], $row['id']); ?></td>
+
+ <!-- Notes -->
+ <td style="text-align: center;" class="<?php echo $cls; ?>"><?php echo yms_notes_cell($row['notes'], $row['id']); ?></td>
+
+ <!-- Actions -->
+ <td style="text-align: center;" class="<?php echo $cls; ?>"><?php echo yms_show_actions($row); ?></td>
+ </tr>
+ <?php
+ }
+ ?>
+
+ </table>
+ </div>
+
+ <br /><br />
+ <a href="<?php echo makeUrlNS('Special', 'YMS/Converter'); ?>" onclick="yms_showpage('Converter'); return false;" class="abutton abutton_red icon"
+ style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/application_view_icons.png);">
+ <?php echo $lang->get('yms_btn_show_converter'); ?>
+ </a>
+
+ <a href="<?php echo makeUrlNS('Special', 'YMS/Converter'); ?>" onclick="yms_showpage('ShowClientInfo'); return false;" class="abutton abutton_blue icon"
+ style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/show_client_info.png);">
+ <?php echo $lang->get('yms_btn_show_client_info'); ?>
+ </a>
+
+ <?php
+ }
+ $db->free_result($q);
+
+ // close off inner div (yms-keylist)
+ if ( !isset($_GET['ajax'] ) )
+ echo '</div>';
+
+ // Send footer
+ $output->footer();
+}
+
+// Add key, using AES secret
+function page_Special_YMS_AddKey()
+{
+ global $output;
+ global $lang;
+
+ $output->header();
+ ?>
+ <h3><?php echo $lang->get('yms_lbl_addkey_heading'); ?></h3>
+ <p><?php echo $lang->get('yms_lbl_addkey_desc'); ?></p>
+ <form action="<?php echo makeUrlNS('Special', 'YMS'); ?>" method="post">
+
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellspacing="4">
+
+ <!-- AES secret -->
+ <tr>
+ <td class="row2">
+ <?php echo $lang->get('yms_lbl_addkey_field_secret'); ?><br />
+ <small><?php echo $lang->get('yms_lbl_addkey_field_secret_hint'); ?></small>
+ </td>
+ <td class="row1">
+ <input type="text" name="add_aes" value="" size="40" />
+ </td>
+ </tr>
+
+ <!-- OTP -->
+ <tr>
+ <td class="row2">
+ <?php echo $lang->get('yms_lbl_addkey_field_otp'); ?>
+ </td>
+ <td class="row1">
+ <?php echo generate_yubikey_field('add_otp'); ?>
+ </td>
+ </tr>
+
+ <!-- State -->
+ <tr>
+ <td class="row2">
+ <?php echo $lang->get('yms_lbl_addkey_field_state'); ?>
+ </td>
+ <td class="row1">
+ <select name="state">
+ <option value="active" selected="selected"><?php echo $lang->get('yms_state_active'); ?></option>
+ <option value="inactive"><?php echo $lang->get('yms_state_inactive'); ?></option>
+ </select>
+ </td>
+ </tr>
+
+ <!-- Any client -->
+ <tr>
+ <td class="row2">
+ <?php echo $lang->get('yms_lbl_addkey_field_any_client_name'); ?><br />
+ <small><?php echo $lang->get('yms_lbl_addkey_field_any_client_hint'); ?></small>
+ </td>
+ <td class="row1">
+ <label>
+ <input type="checkbox" name="any_client" />
+ <?php echo $lang->get('yms_lbl_addkey_field_any_client'); ?>
+ </label>
+ </td>
+ </tr>
+
+ <!-- Notes -->
+ <tr>
+ <td class="row2">
+ <?php echo $lang->get('yms_lbl_addkey_field_notes'); ?>
+ </td>
+ <td class="row1">
+ <textarea style="font-family: sans-serif; font-size: 9pt;" name="notes" rows="5" cols="40"></textarea>
+ </td>
+ </tr>
+
+ <!-- Submit -->
+ <tr>
+ <th class="subhead" colspan="2">
+ <input type="submit" value="<?php echo $lang->get('yms_btn_addkey_submit'); ?>" />
+ </th>
+ </tr>
+
+ </table>
+ </div>
+
+ </form>
+ <?php
+ $output->footer();
+}
+
+// Add key that's already registered
+function page_Special_YMS_AddPreregisteredKey()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang, $output;
+
+ $output->header();
+ ?>
+ <h3><?php echo $lang->get('yms_lbl_claimkey_heading'); ?></h3>
+ <p><?php echo $lang->get('yms_lbl_claimkey_desc'); ?></p>
+ <form action="<?php echo makeUrlNS('Special', 'YMS'); ?>" method="post">
+
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellspacing="4">
+
+ <!-- OTP -->
+ <tr>
+ <td class="row2">
+ <?php echo $lang->get('yms_lbl_addkey_field_otp'); ?>
+ </td>
+ <td class="row1">
+ <?php echo generate_yubikey_field('claim_otp'); ?>
+ </td>
+ </tr>
+
+ <!-- State -->
+ <tr>
+ <td class="row2">
+ <?php echo $lang->get('yms_lbl_addkey_field_state'); ?>
+ </td>
+ <td class="row1">
+ <select name="state">
+ <option value="active" selected="selected"><?php echo $lang->get('yms_state_active'); ?></option>
+ <option value="inactive"><?php echo $lang->get('yms_state_inactive'); ?></option>
+ </select>
+ </td>
+ </tr>
+
+ <!-- Any client -->
+ <tr>
+ <td class="row2">
+ <?php echo $lang->get('yms_lbl_addkey_field_any_client_name'); ?><br />
+ <small><?php echo $lang->get('yms_lbl_addkey_field_any_client_hint'); ?></small>
+ </td>
+ <td class="row1">
+ <label>
+ <input type="checkbox" name="any_client" />
+ <?php echo $lang->get('yms_lbl_addkey_field_any_client'); ?>
+ </label>
+ </td>
+ </tr>
+
+ <!-- Notes -->
+ <tr>
+ <td class="row2">
+ <?php echo $lang->get('yms_lbl_addkey_field_notes'); ?>
+ </td>
+ <td class="row1">
+ <textarea style="font-family: sans-serif; font-size: 9pt;" name="notes" rows="5" cols="40"></textarea>
+ </td>
+ </tr>
+
+ <?php if ( ($field = getConfig('yms_claim_auth_field', '')) && getConfig('yms_claim_auth_url') ): ?>
+ <!-- Custom field -->
+ <tr>
+ <td class="row2">
+ <?php echo htmlspecialchars($field); ?>
+ </td>
+ <td class="row1">
+ <input type="text" name="custom_field" value="" size="30" />
+ </td>
+ </tr>
+ <?php endif; ?>
+
+ <!-- Submit -->
+ <tr>
+ <th class="subhead" colspan="2">
+ <input type="submit" value="<?php echo $lang->get('yms_btn_addkey_submit'); ?>" />
+ </th>
+ </tr>
+
+ </table>
+ </div>
+
+ </form>
+ <?php
+ $output->footer();
+}
+
+// Show the AES secret for a key
+function page_Special_YMS_ShowAESKey()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang, $output;
+
+ $id = intval($paths->getParam(1));
+
+ // verify ownership, retrieve key
+ $q = $db->sql_query('SELECT client_id, public_id, aes_secret FROM ' . table_prefix . "yms_yubikeys WHERE id = $id;");
+ if ( !$q )
+ $db->_die();
+
+ if ( $db->numrows() < 1 )
+ {
+ die_friendly('no rows', '<p>key not found</p>');
+ }
+
+ list($client_id, $public_id, $secret) = $db->fetchrow_num();
+ $db->free_result();
+
+ if ( $client_id !== $session->user_id )
+ die_friendly($lang->get('etc_access_denied_short'), '<p>' . $lang->get('etc_access_denied') . '</p>');
+
+ $output->header();
+ ?>
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">
+ <?php echo $lang->get('yms_showaes_th', array('public_id' => yms_modhex_encode($public_id))); ?>
+ </th>
+ </tr>
+
+ <!-- hex -->
+ <tr>
+ <td class="row2" style="width: 50%;">
+ <?php echo $lang->get('yms_showaes_lbl_hex'); ?>
+ </td>
+ <td class="row1">
+ <?php echo $secret; ?>
+ </td>
+ </tr>
+
+ <!-- modhex -->
+ <tr>
+ <td class="row2">
+ <?php echo $lang->get('yms_showaes_lbl_modhex'); ?>
+ </td>
+ <td class="row1">
+ <?php echo yms_modhex_encode($secret); ?>
+ </td>
+ </tr>
+
+ <!-- base64 -->
+ <tr>
+ <td class="row2">
+ <?php echo $lang->get('yms_showaes_lbl_base64'); ?>
+ </td>
+ <td class="row1">
+ <?php echo base64_encode(yms_tobinary($secret)); ?>
+ </td>
+ </tr>
+
+ </table>
+ </div>
+ <?php
+ $output->footer();
+}
+
+// show the user's API key and client ID
+function page_Special_YMS_ShowClientInfo()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang, $output;
+
+ $q = $db->sql_query('SELECT apikey FROM ' . table_prefix . "yms_clients WHERE id = {$session->user_id};");
+ if ( !$q )
+ $db->_die();
+
+ list($api_key) = $db->fetchrow_num();
+ $db->free_result();
+
+ $api_key = yms_tobinary($api_key);
+
+ $output->header();
+ ?>
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+
+ <tr>
+ <th colspan="2"><?php echo $lang->get('yms_th_client_id'); ?></th>
+ </tr>
+
+ <tr>
+ <td class="row2"><?php echo $lang->get('yms_lbl_client_id'); ?></td>
+ <td class="row1"><?php echo strval($session->user_id); ?></td>
+ </tr>
+
+ <tr>
+ <th colspan="2"><?php echo $lang->get('yms_th_api_key'); ?></th>
+ </tr>
+
+ <tr>
+ <td class="row2"><?php echo $lang->get('yms_showaes_lbl_hex'); ?></td>
+ <td class="row1"><?php echo yms_hex_encode($api_key); ?></td>
+ </tr>
+
+ <tr>
+ <td class="row2"><?php echo $lang->get('yms_showaes_lbl_modhex'); ?></td>
+ <td class="row1"><?php echo yms_modhex_encode($api_key); ?></td>
+ </tr>
+
+ <tr>
+ <td class="row2"><?php echo $lang->get('yms_showaes_lbl_base64'); ?></td>
+ <td class="row1"><?php echo base64_encode($api_key); ?></td>
+ </tr>
+
+ </table>
+ </div>
+ <?php
+ $output->footer();
+}
+
+// Converter between different binary encodings
+function page_Special_YMS_Converter()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang, $output;
+
+ $output->header();
+
+ if ( isset($_POST['value']) )
+ {
+ switch($_POST['format'])
+ {
+ case 'auto':
+ default:
+ $binary = yms_tobinary($_POST['value']);
+ break;
+ case 'hex':
+ $_POST['value'] = str_replace(" ", '', $_POST['value']);
+ $binary = yms_hex_decode($_POST['value']);
+ break;
+ case 'modhex':
+ $binary = yms_hex_decode(yms_modhex_decode($_POST['value']));
+ break;
+ case 'base64':
+ $binary = base64_decode($_POST['value']);
+ break;
+ }
+
+ if ( empty($binary) )
+ {
+ echo '<div class="error-box">' . $lang->get('yms_conv_err_invalid_string') . '</div>';
+ }
+ else
+ {
+ ?>
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+
+ <tr>
+ <th colspan="2"><?php echo $lang->get('yms_th_converted_value'); ?></th>
+ </tr>
+
+ <tr>
+ <td class="row2"><?php echo $lang->get('yms_showaes_lbl_hex'); ?></td>
+ <td class="row1"><?php echo yms_hex_encode($binary); ?></td>
+ </tr>
+
+ <tr>
+ <td class="row2"><?php echo $lang->get('yms_showaes_lbl_modhex'); ?></td>
+ <td class="row1"><?php echo yms_modhex_encode($binary); ?></td>
+ </tr>
+
+ <tr>
+ <td class="row2"><?php echo $lang->get('yms_showaes_lbl_base64'); ?></td>
+ <td class="row1"><?php echo base64_encode($binary); ?></td>
+ </tr>
+
+ </table>
+ </div>
+ <?php
+ }
+ }
+
+ ?>
+ <form method="post" class="submit_to_self" action="<?php echo makeUrl($paths->fullpage); ?>">
+
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+
+ <tr>
+ <th colspan="2"><?php echo $lang->get('yms_th_converter'); ?></th>
+ </tr>
+
+ <tr>
+ <td class="row2" style="width: 30%;"><?php echo $lang->get('yms_conv_lbl_value'); ?></td>
+ <td class="row1"><input type="text" name="value" size="60" /></td>
+ </tr>
+
+ <tr>
+ <td class="row2" style="width: 30%;"><?php echo $lang->get('yms_conv_lbl_format'); ?></td>
+ <td class="row1">
+ <?php
+ foreach ( array('auto', 'hex', 'modhex', 'base64') as $i => $fmt )
+ {
+ echo '<label><input type="radio" name="format" value="' . $fmt . '" ';
+ if ( ( isset($_POST['format']) && $_POST['format'] === $fmt ) || ( !isset($_POST['format']) && $i == 0 ) )
+ echo 'checked="checked" ';
+
+ echo '/> ';
+ echo $lang->get("yms_conv_lbl_format_$fmt");
+ echo "</label>\n ";
+ }
+ ?>
+ </td>
+ </tr>
+
+ <tr>
+ <th class="subhead" colspan="2">
+ <input type="submit" value="<?php echo $lang->get('yms_conv_btn_submit'); ?>" />
+ </th>
+ </tr>
+
+ </table>
+ </div>
+
+ </form>
+ <?php
+
+ $output->footer();
+}
+
+function page_Special_YMS_AjaxToggleState()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ $id = intval($_POST['id']);
+ if ( $_POST['state'] === 'active' )
+ $expr = 'flags | ' . YMS_ENABLED;
+ else
+ $expr = 'flags & ~' . YMS_ENABLED;
+
+ $q = $db->sql_query('UPDATE ' . table_prefix . "yms_yubikeys SET flags = $expr WHERE id = $id AND client_id = {$session->user_id};");
+ if ( !$q )
+ $db->die_json();
+
+ if ( $db->sql_affectedrows() < 1 )
+ echo 'no affected rows; not ';
+
+ echo 'ok';
+}
+
+function page_Special_YMS_AjaxNotes()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if ( isset($_POST['get']) )
+ {
+ $id = intval($_POST['get']);
+ $q = $db->sql_query('SELECT notes FROM ' . table_prefix . "yms_yubikeys WHERE id = $id AND client_id = {$session->user_id};");
+ if ( !$q )
+ $db->_die();
+ if ( $db->numrows() < 1 )
+ {
+ echo "key not found";
+ }
+ else
+ {
+ list($note) = $db->fetchrow_num();
+ echo $note;
+ }
+ $db->free_result();
+ }
+ else if ( isset($_POST['save']) )
+ {
+ $id = intval($_POST['save']);
+ $note = trim($_POST['note']);
+ $note = $db->escape($note);
+ $q = $db->sql_query('UPDATE ' . table_prefix . "yms_yubikeys SET notes = '$note' WHERE id = $id AND client_id = {$session->user_id};");
+ if ( !$q )
+ $db->die_json();
+
+ echo 'ok';
+ }
+}
+
+// Add key, using just an OTP
+// Requires the key to be in the database as client ID 0
+
+// Client creation
+function page_Special_YMSCreateClient()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang;
+ global $output;
+
+ // Require re-auth?
+ if ( $session->auth_level < USER_LEVEL_CHPREF && getConfig('yms_require_reauth', 1) == 1 )
+ {
+ redirect(makeUrlNS('Special', "Login/$paths->fullpage", 'level=' . USER_LEVEL_CHPREF), '', '', 0);
+ }
+
+ // Check for Yubikey plugin
+ if ( !function_exists('yubikey_validate_otp') )
+ {
+ die_friendly($lang->get('yms_err_yubikey_plugin_missing_title'), '<p>' . $lang->get('yms_err_yubikey_plugin_missing_body') . '</p>');
+ }
+
+ // Does the client exist?
+ $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . "yms_clients WHERE id = {$session->user_id};");
+ if ( !$q )
+ $db->_die();
+
+ $client_exists = $db->numrows();
+ $db->free_result();
+
+ if ( $client_exists )
+ {
+ die_friendly($lang->get('yms_err_client_exists_title'), '<p>' . $lang->get('yms_err_client_exists_body') . '</p>');
+ }
+
+ $template->add_header('<link rel="stylesheet" type="text/css" href="' . scriptPath . '/plugins/yms/styles.css" />');
+ $output->header();
+
+ if ( isset($_POST['register_client']) )
+ {
+ // register the client
+ // SHA1 key length: 160 bits
+ $api_key = base64_encode(AESCrypt::randkey(160 / 8));
+ $client_id = $session->user_id;
+
+ $q = $db->sql_query('INSERT INTO ' . table_prefix . "yms_clients(id, apikey) VALUES ($client_id, '$api_key');");
+ if ( !$q )
+ $db->_die();
+
+ $validate_url = makeUrlComplete('Special', 'YubikeyValidate');
+ $validate_url = preg_replace('/[?&]auth=[0-9a-f]+/', '', $validate_url);
+
+ ?>
+ <h3><?php echo $lang->get('yms_register_msg_success_title'); ?></h3>
+ <?php echo $lang->get('yms_register_msg_success_body', array(
+ 'yms_link' => makeUrlNS('Special', 'YMS'),
+ 'client_id' => $client_id,
+ 'api_key' => $api_key,
+ 'validate_url' => $validate_url
+ ));
+ }
+ else
+ {
+ // confirmation page
+ ?>
+ <form action="<?php echo makeUrlNS('Special', 'YMSCreateClient'); ?>" method="post">
+ <h3><?php echo $lang->get('yms_register_confirm_title'); ?></h3>
+ <p><?php echo $lang->get('yms_register_confirm_body'); ?></p>
+ <p>
+ <input type="submit" style="font-weight: bold;" name="register_client" value="<?php echo $lang->get('yms_register_btn_submit'); ?>" />
+ <input type="submit" name="cancel" value="<?php echo $lang->get('etc_cancel'); ?>" />
+ </p>
+ </form>
+ <?php
+ }
+
+ $output->footer();
+}
+
+// Generic response function
+// Processing functions return either true or a string containing an error message. This
+// takes that return, and sends a response through the appropriate channel, while allowing
+// shared backend functions.
+
+function yms_send_response($success_string, $result)
+{
+ global $lang, $output;
+
+ if ( $result === true )
+ {
+ if ( isset($_GET['ajax']) )
+ {
+ yms_json_response(array(
+ 'mode' => 'success',
+ 'message' => $lang->get($success_string)
+ ));
+ }
+ else
+ {
+ $output->add_after_header(
+ '<div class="info-box">' . $lang->get($success_string) . '</div>'
+ );
+ }
+ }
+ else
+ {
+ if ( isset($_GET['ajax']) )
+ {
+ yms_json_response(array(
+ 'mode' => 'error',
+ 'error' => $lang->get($result)
+ ));
+ }
+ else
+ {
+ $output->add_after_header(
+ '<div class="error-box">' . $lang->get($result) . '</div>'
+ );
+ }
+ }
+}
+
+function yms_json_response($response)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ header('Content-type: application/json');
+ echo enano_json_encode($response);
+
+ $db->close();
+ exit;
+}
+
+function yms_date($ts)
+{
+ return enano_date('Y-m-d H:m:i', $ts);
+}
+
+function yms_state_indicator($flags, $id)
+{
+ global $lang;
+ return $flags & YMS_ENABLED ?
+ '<span onclick="yms_toggle_state(this, ' . $id . ');" class="yms-enabled">' . $lang->get('yms_state_active') . '</span>' :
+ '<span onclick="yms_toggle_state(this, ' . $id . ');" class="yms-disabled">' . $lang->get('yms_state_inactive') . '</span>';
+}
+
+function yms_notes_cell($notes, $id)
+{
+ global $lang;
+ $notes = trim($notes);
+ if ( empty($notes) )
+ {
+ $img = 'note_delete.png';
+ $str = $lang->get('yms_btn_note_create');
+ }
+ else
+ {
+ $img = 'note.png';
+ $str = $lang->get('yms_btn_note_view');
+ }
+ echo '<a href="#" onclick="yms_show_notes(this, '.$id.'); return false;" title="' . $str . '"><img alt="' . $str . '" src="' . scriptPath . '/plugins/yms/icons/' . $img . '" /></a>';
+
+ if ( !empty($notes) )
+ {
+ echo ' ';
+ if ( strlen($notes) > 15 )
+ echo htmlspecialchars(substr($notes, 0, 12)) . '...';
+ else
+ echo htmlspecialchars($notes);
+ }
+}
+
+function yms_show_actions($row)
+{
+ global $lang;
+
+ // Show AES secret
+ ?>
+ <a href="<?php echo makeUrlNS('Special', "YMS/ShowAESKey/{$row['id']}"); ?>" title="<?php echo $lang->get('yms_btn_show_aes'); ?>" onclick="yms_showpage('ShowAESKey/<?php echo $row['id']; ?>'); return false;">
+ <img alt="<?php echo $lang->get('yms_btn_show_aes'); ?>" src="<?php echo scriptPath; ?>/plugins/yms/icons/key_go.png" />
+ </a>
+ <?php
+}