|
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 |