plugins/yubikey/usercp.php
changeset 0 9d2c4f04a0d0
child 3 d0fe7acaf0e8
equal deleted inserted replaced
-1:000000000000 0:9d2c4f04a0d0
       
     1 <?php
       
     2 
       
     3 $plugins->attachHook("userprefs_jbox", "yubikey_ucp_setup();");
       
     4 $plugins->attachHook("userprefs_body", "return yubikey_user_cp(\$section);");
       
     5 $plugins->attachHook("login_form_html", "yubikey_inject_html_login();");
       
     6 
       
     7 function yubikey_ucp_setup()
       
     8 {
       
     9   userprefs_menu_add('usercp_sec_profile', 'yubiucp_panel_title', makeUrlNS('Special', 'Preferences/Yubikey'));
       
    10 }
       
    11 
       
    12 function yubikey_user_cp($section)
       
    13 {
       
    14   global $db, $session, $paths, $template, $plugins; // Common objects
       
    15   global $lang;
       
    16   
       
    17   if ( $section !== 'Yubikey' )
       
    18     return false;
       
    19   
       
    20   $count_enabled = intval(getConfig('yubikey_enroll_limit', '3'));
       
    21   
       
    22   if ( isset($_POST['submit']) )
       
    23   {
       
    24     csrf_request_confirm();
       
    25     
       
    26     $keys = array();
       
    27     if ( isset($_POST['yubikey_enable']) )
       
    28     {
       
    29       for ( $i = 0; $i < $count_enabled; $i++ )
       
    30       {
       
    31         if ( !empty($_POST["yubikey_otp_$i"]) )
       
    32         {
       
    33           $ckey =& $_POST["yubikey_otp_$i"];
       
    34           if ( preg_match('/^[cbdefghijklnrtuv]{12,44}$/', $ckey) )
       
    35           {
       
    36             $ckey = substr($ckey, 0, 12);
       
    37             $keys[] = $ckey;
       
    38           }
       
    39           unset($ckey);
       
    40         }
       
    41       }
       
    42     }
       
    43     // Check for double enrollment
       
    44     $keys_check = "yubi_uid = '" . implode("' OR yubi_uid = '", $keys) . "'";
       
    45     $q = $db->sql_query('SELECT yubi_uid FROM ' . table_prefix . "yubikey WHERE ( $keys_check ) AND user_id != {$session->user_id};");
       
    46     if ( !$q )
       
    47       $db->_die();
       
    48     
       
    49     if ( $db->numrows() > 0 )
       
    50     {
       
    51       echo '<div class="error-box" style="margin: 0 0 10px 0;">' . $lang->get('yubiucp_err_double_enrollment') . '</div>';
       
    52       while ( $row = $db->fetchrow() )
       
    53       {
       
    54         foreach ( $keys as $i => $key )
       
    55         {
       
    56           if ( $key == $row['yubi_uid'] )
       
    57           {
       
    58             unset($keys[$i]);
       
    59           }
       
    60         }
       
    61       }
       
    62       $keys = array_values($keys);
       
    63     }
       
    64     $db->free_result();
       
    65     
       
    66     // Remove all currently registered keys
       
    67     $q = $db->sql_query('DELETE FROM ' . table_prefix . "yubikey WHERE user_id = {$session->user_id};");
       
    68     if ( !$q )
       
    69       $db->_die();
       
    70     
       
    71     // Enroll any new keys
       
    72     if ( !empty($keys) )
       
    73     {
       
    74       $query = 'INSERT INTO ' . table_prefix . "yubikey(user_id, yubi_uid) VALUES\n  " .
       
    75                  "( $session->user_id, '" . implode("' ),\n  ( $session->user_id, '", $keys) . "' );";
       
    76       if ( !$db->sql_query($query) )
       
    77         $db->_die();
       
    78     }
       
    79     
       
    80     // Calculate flags
       
    81     $yubi_flags = 0;
       
    82     $yubi_flags |= intval($_POST['login_normal_flags']);
       
    83     $yubi_flags |= intval($_POST['login_elev_flags']);
       
    84     $yubi_flags |= ( isset($_POST['allow_no_yubikey']) ) ? YK_SEC_ALLOW_NO_OTP : 0;
       
    85     
       
    86     // update flags
       
    87     $q = $db->sql_query('UPDATE ' . table_prefix . "users SET user_yubikey_flags = $yubi_flags WHERE user_id = {$session->user_id};");
       
    88     if ( !$q )
       
    89       $db->_die();
       
    90   }
       
    91   else
       
    92   {
       
    93     // Fetch flags
       
    94     $q = $db->sql_query('SELECT user_yubikey_flags FROM ' . table_prefix . "users WHERE user_id = {$session->user_id};");
       
    95     if ( !$q )
       
    96       $db->_die();
       
    97     
       
    98     list($yubi_flags) = $db->fetchrow_num();
       
    99     $yubi_flags = intval($yubi_flags);
       
   100     // Fetch user's authorized keys from the DB
       
   101     $q = $db->sql_query('SELECT yubi_uid FROM ' . table_prefix . "yubikey WHERE user_id = {$session->user_id};");
       
   102     if ( !$q )
       
   103       $db->_die();
       
   104     
       
   105     $keys = array();
       
   106     while ( $row = $db->fetchrow() )
       
   107     {
       
   108       $keys[] = $row['yubi_uid'];
       
   109     }
       
   110     $db->free_result();
       
   111   }
       
   112   
       
   113   while ( count($keys) < $count_enabled )
       
   114   {
       
   115     $keys[] = false;
       
   116   }
       
   117   
       
   118   $enable_checked = ( $keys[0] === false && !isset($_POST['yubikey_enable']) ) ? '' : 'checked="checked"';
       
   119   $displaytable = ( $keys[0] === false && !isset($_POST['yubikey_enable']) ) ? 'none' : 'block';
       
   120   
       
   121   $check_normal_keyonly = ( !($yubi_flags & YK_SEC_NORMAL_USERNAME) && !($yubi_flags & YK_SEC_NORMAL_PASSWORD) ) ? 'checked="checked" ' : '';
       
   122   $check_normal_username = ( ($yubi_flags & YK_SEC_NORMAL_USERNAME) && !($yubi_flags & YK_SEC_NORMAL_PASSWORD) ) ? 'checked="checked" ' : '';
       
   123   $check_normal_userandpw = ( ($yubi_flags & YK_SEC_NORMAL_USERNAME) && ($yubi_flags & YK_SEC_NORMAL_PASSWORD) ) ? 'checked="checked" ' : '';
       
   124 
       
   125   $check_elev_keyonly = ( !($yubi_flags & YK_SEC_ELEV_USERNAME) && !($yubi_flags & YK_SEC_ELEV_PASSWORD) ) ? 'checked="checked" ' : '';
       
   126   $check_elev_username = ( ($yubi_flags & YK_SEC_ELEV_USERNAME) && !($yubi_flags & YK_SEC_ELEV_PASSWORD) ) ? 'checked="checked" ' : '';
       
   127   $check_elev_userandpw = ( ($yubi_flags & YK_SEC_ELEV_USERNAME) && ($yubi_flags & YK_SEC_ELEV_PASSWORD) ) ? 'checked="checked" ' : '';  
       
   128   
       
   129   ?>
       
   130   <h3 style="margin-top: 0;"><?php echo $lang->get('yubiucp_panel_title'); ?></h3>
       
   131   
       
   132   <form action="<?php echo makeUrlNS('Special', 'Preferences/Yubikey'); ?>" method="post">
       
   133   
       
   134   <div>
       
   135     <table border="0" cellpadding="4" width="100%">
       
   136       <tr>
       
   137         <td style="width: 50%; text-align: right;">
       
   138           <?php echo $lang->get('yubiucp_field_enable_title'); ?><br />
       
   139           <small><?php echo $lang->get('yubiucp_field_enable_hint'); ?></small>
       
   140         </td>
       
   141         <td style="width: 50%;">
       
   142           <label>
       
   143             <input type="checkbox" name="yubikey_enable" onclick="if ( $(this).attr('checked') ) $('#yk_useroptions').show('blind'); else $('#yk_useroptions').hide('blind');" <?php echo $enable_checked; ?> />
       
   144             <?php echo $lang->get('yubiucp_field_enable'); ?>
       
   145           </label>
       
   146         </td>
       
   147       </tr>
       
   148     </table>
       
   149     <table border="0" cellpadding="4" width="100%" id="yk_useroptions" style="display: <?php echo $displaytable ?>;">
       
   150       <tr class="yk_alt1">
       
   151       <td style="width: 50%; text-align: right;">
       
   152           <?php echo $lang->get('yubiucp_field_keys_title'); ?><br />
       
   153           <small><?php
       
   154           echo $lang->get('yubiucp_field_keys_hint');
       
   155           if ( $count_enabled > 1 )
       
   156           {
       
   157             echo ' ';
       
   158             echo $lang->get('yubiucp_field_keys_maximum', array('max' => $count_enabled));
       
   159           }
       
   160           ?></small>
       
   161         </td>
       
   162         <td style="width: 50%;">
       
   163           <?php
       
   164           for ( $i = 0; $i < $count_enabled; $i++ )
       
   165           {
       
   166             echo '<p>' . generate_yubikey_field('yubikey_otp_' . $i, $keys[$i]) . '</p>';
       
   167           }
       
   168           ?>
       
   169         </td>
       
   170       </tr>
       
   171       <tr>
       
   172         <td style="width: 50%; text-align: right;">
       
   173           <?php echo $lang->get('yubiucp_field_normal_flags'); ?>
       
   174         </td>
       
   175         <td>
       
   176           <label>
       
   177             <input type="radio" name="login_normal_flags" value="0" <?php echo $check_normal_keyonly; ?>/>
       
   178             <?php echo $lang->get('yubiucp_field_flags_keyonly'); ?>
       
   179           </label>
       
   180           
       
   181           <br />
       
   182           
       
   183           <label>
       
   184             <input type="radio" name="login_normal_flags" value="<?php echo strval(YK_SEC_NORMAL_USERNAME); ?>" <?php echo $check_normal_username; ?>/>
       
   185             <?php echo $lang->get('yubiucp_field_flags_username'); ?>
       
   186           </label>
       
   187           
       
   188           <br />
       
   189           
       
   190           <label>
       
   191             <input type="radio" name="login_normal_flags" value="<?php echo strval(YK_SEC_NORMAL_USERNAME | YK_SEC_NORMAL_PASSWORD); ?>" <?php echo $check_normal_userandpw; ?>/>
       
   192             <?php echo $lang->get('yubiucp_field_flags_userandpw'); ?>
       
   193           </label>
       
   194         </td>
       
   195       </tr>
       
   196       <tr class="yk_alt1">
       
   197         <td style="width: 50%; text-align: right;">
       
   198           <?php echo $lang->get('yubiucp_field_elev_flags'); ?>
       
   199         </td>
       
   200         <td>
       
   201           <label>
       
   202             <input type="radio" name="login_elev_flags" value="0" <?php echo $check_elev_keyonly; ?>/>
       
   203             <?php echo $lang->get('yubiucp_field_flags_keyonly'); ?>
       
   204           </label>
       
   205           
       
   206           <br />
       
   207           
       
   208           <label>
       
   209             <input type="radio" name="login_elev_flags" value="<?php echo strval(YK_SEC_ELEV_USERNAME); ?>" <?php echo $check_elev_username; ?>/>
       
   210             <?php echo $lang->get('yubiucp_field_flags_username'); ?>
       
   211           </label>
       
   212           
       
   213           <br />
       
   214           
       
   215           <label>
       
   216             <input type="radio" name="login_elev_flags" value="<?php echo strval(YK_SEC_ELEV_USERNAME | YK_SEC_ELEV_PASSWORD); ?>" <?php echo $check_elev_userandpw; ?>/>
       
   217             <?php echo $lang->get('yubiucp_field_flags_userandpw'); ?>
       
   218           </label>
       
   219         </td>
       
   220       </tr>
       
   221       <tr>
       
   222         <td>
       
   223         </td>
       
   224         <td>
       
   225           <label>
       
   226             <input type="checkbox" name="allow_no_yubikey" <?php if ( $yubi_flags & YK_SEC_ALLOW_NO_OTP ) echo 'checked="checked" '; ?>/>
       
   227             <?php echo $lang->get('yubiucp_field_allow_plain_login'); ?>
       
   228           </label>
       
   229           <br />
       
   230           <small>
       
   231             <?php echo $lang->get('yubiucp_field_allow_plain_login_hint'); ?>
       
   232           </small>
       
   233         </td>
       
   234       </tr>
       
   235     </table>
       
   236     <table border="0" cellpadding="4" width="100%">
       
   237       <tr class="yk_alt1">
       
   238         <td colspan="2" style="text-align: center;">
       
   239           <input type="submit" name="submit" value="<?php echo $lang->get('etc_save_changes'); ?>" />
       
   240         </td>
       
   241       </tr>
       
   242     </table>
       
   243   </div>
       
   244   
       
   245   <input type="hidden" name="cstok" value="<?php echo $session->csrf_token; ?>" />
       
   246   
       
   247   </form>
       
   248   <?php
       
   249   
       
   250   return true;
       
   251 }
       
   252 
       
   253 function yubikey_inject_html_login()
       
   254 {
       
   255   global $lang;
       
   256   ?>
       
   257   <tr>
       
   258     <td class="row2">
       
   259       <?php echo $lang->get('yubiauth_lbl_otp_field'); ?>
       
   260     </td>
       
   261     <td class="row1" colspan="2">
       
   262       <input type="text" size="40" class="yubikey_noscript" name="yubikey_otp" />
       
   263     </td>
       
   264   </tr>
       
   265   <?php
       
   266 }
       
   267