|
1 <?php |
|
2 |
|
3 function page_Special_YMS() |
|
4 { |
|
5 global $db, $session, $paths, $template, $plugins; // Common objects |
|
6 global $lang; |
|
7 global $output; |
|
8 |
|
9 // Require re-auth? |
|
10 if ( $session->auth_level < USER_LEVEL_CHPREF && getConfig('yms_require_reauth', 1) == 1 ) |
|
11 { |
|
12 redirect(makeUrlNS('Special', "Login/$paths->fullpage", 'level=' . USER_LEVEL_CHPREF), '', '', 0); |
|
13 } |
|
14 |
|
15 // Check for Yubikey plugin |
|
16 if ( !function_exists('yubikey_validate_otp') ) |
|
17 { |
|
18 die_friendly($lang->get('yms_err_yubikey_plugin_missing_title'), '<p>' . $lang->get('yms_err_yubikey_plugin_missing_body') . '</p>'); |
|
19 } |
|
20 |
|
21 // Does the client exist? |
|
22 $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . "yms_clients WHERE id = {$session->user_id};"); |
|
23 if ( !$q ) |
|
24 $db->_die(); |
|
25 |
|
26 $client_exists = $db->numrows(); |
|
27 $db->free_result(); |
|
28 if ( !$client_exists ) |
|
29 { |
|
30 redirect(makeUrlNS('Special', 'YMSCreateClient'), '', '', 0); |
|
31 } |
|
32 |
|
33 // Check for a subpage request |
|
34 if ( $subpage = $paths->getParam(0) ) |
|
35 { |
|
36 if ( preg_match('/^[A-z0-9]+$/', $subpage) ) |
|
37 { |
|
38 if ( function_exists("page_Special_YMS_{$subpage}") ) |
|
39 { |
|
40 // call the subpage |
|
41 return call_user_func("page_Special_YMS_{$subpage}"); |
|
42 } |
|
43 } |
|
44 } |
|
45 |
|
46 // |
|
47 // POST processing |
|
48 // |
|
49 |
|
50 if ( isset($_POST['add_aes']) && isset($_POST['add_otp']) ) |
|
51 { |
|
52 $client_id = false; |
|
53 $enabled = $_POST['state'] == 'active'; |
|
54 $any_client = isset($_POST['any_client']); |
|
55 $notes = $_POST['notes']; |
|
56 $result = yms_add_yubikey($_POST['add_aes'], $_POST['add_otp'], $client_id, $enabled, $any_client, $notes); |
|
57 yms_send_response('yms_msg_addkey_success', $result); |
|
58 } |
|
59 else if ( isset($_POST['claim_otp']) ) |
|
60 { |
|
61 // do we need to validate a custom field? |
|
62 if ( ($url = getConfig('yms_claim_auth_url')) && getConfig('yms_claim_auth_field') ) |
|
63 { |
|
64 if ( ($result = yms_validate_custom_field($_POST['custom_field'], $_POST['claim_otp'], $url)) !== true ) |
|
65 yms_send_response('n/a', $result); |
|
66 } |
|
67 |
|
68 // validate this OTP, make sure it's all good |
|
69 $result = strtolower(yms_validate_otp($_POST['claim_otp'], 0)); |
|
70 if ( $result !== 'ok' ) |
|
71 yms_send_response('n/a', "yubiauth_err_response_{$result}"); |
|
72 |
|
73 // change owner |
|
74 $client_id = false; |
|
75 $enabled = $_POST['state'] == 'active'; |
|
76 $any_client = isset($_POST['any_client']); |
|
77 $notes = $_POST['notes']; |
|
78 $result = yms_chown_yubikey($_POST['claim_otp'], $client_id, $enabled, $any_client, $notes); |
|
79 yms_send_response('yms_msg_addkey_success', $result); |
|
80 } |
|
81 |
|
82 // Preload JS libraries we need for Yubikey |
|
83 $template->preload_js(array('jquery', 'jquery-ui', 'l10n', 'flyin', 'messagebox', 'fadefilter')); |
|
84 // Load CSS |
|
85 $template->add_header('<link rel="stylesheet" type="text/css" href="' . scriptPath . '/plugins/yms/styles.css" />'); |
|
86 // Load JS |
|
87 $template->add_header('<script type="text/javascript" src="' . scriptPath . '/plugins/yms/cp.js"></script>'); |
|
88 |
|
89 // Send header |
|
90 $output->header(); |
|
91 |
|
92 // Message container |
|
93 if ( !isset($_GET['ajax'] ) ) |
|
94 echo '<div id="yms-messages"></div><div id="yms-keylist">'; |
|
95 |
|
96 // Buttons |
|
97 ?> |
|
98 <div class="yms-buttons"> |
|
99 <a class="abutton abutton_green icon" style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/key_add.png);" |
|
100 href="<?php echo makeUrlNS('Special', 'YMS/AddKey'); ?>" onclick="yms_showpage('AddKey'); return false;"> |
|
101 <?php echo $lang->get('yms_btn_add_key'); ?> |
|
102 </a> |
|
103 <a class="abutton abutton_blue icon" style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/key_add.png);" |
|
104 href="<?php echo makeUrlNS('Special', 'YMS/AddPreregisteredKey'); ?>" onclick="yms_showpage('AddPreregisteredKey'); return false;"> |
|
105 <?php echo $lang->get('yms_btn_add_key_preregistered'); ?> |
|
106 </a> |
|
107 </div> |
|
108 <?php |
|
109 |
|
110 // Pull all Yubikeys |
|
111 $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};"); |
|
112 if ( !$q ) |
|
113 $db->_die(); |
|
114 |
|
115 if ( $db->numrows() < 1 ) |
|
116 { |
|
117 echo '<h2 class="emptymessage">' . $lang->get('yms_msg_no_yubikeys') . '</h2>'; |
|
118 } |
|
119 else |
|
120 { |
|
121 ?> |
|
122 <div class="tblholder"> |
|
123 <table border="0" cellspacing="1" cellpadding="4"> |
|
124 |
|
125 <!-- Table header --> |
|
126 <tr> |
|
127 <th><?php echo $lang->get('yms_th_id'); ?></th> |
|
128 <th><?php echo $lang->get('yms_th_publicid'); ?></th> |
|
129 <th><?php echo $lang->get('yms_th_createtime'); ?></th> |
|
130 <th><?php echo $lang->get('yms_th_accesstime'); ?></th> |
|
131 <th><?php echo $lang->get('yms_th_state'); ?></th> |
|
132 <th><?php echo $lang->get('yms_th_note'); ?></th> |
|
133 <th></th> |
|
134 </tr> |
|
135 |
|
136 <?php |
|
137 $cls = 'row2'; |
|
138 while ( $row = $db->fetchrow($q) ) |
|
139 { |
|
140 $cls = $cls == 'row2' ? 'row1' : 'row2'; |
|
141 ?> |
|
142 <tr> |
|
143 <!-- Key ID --> |
|
144 <td style="text-align: center;" class="<?php echo $cls; ?>"><?php echo $row['id']; ?></td> |
|
145 |
|
146 <!-- Public UID --> |
|
147 <td style="text-align: left;" class="<?php echo $cls; ?>"><?php echo yms_modhex_encode($row['public_id']); ?></td> |
|
148 |
|
149 <!-- Create time --> |
|
150 <td style="text-align: left;" class="<?php echo $cls; ?>"><?php echo yms_date($row['create_time']); ?></td> |
|
151 |
|
152 <!-- Access time --> |
|
153 <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> |
|
154 |
|
155 <!-- State --> |
|
156 <td style="text-align: center;" class="<?php echo $cls; ?>"><?php echo yms_state_indicator($row['flags'], $row['id']); ?></td> |
|
157 |
|
158 <!-- Notes --> |
|
159 <td style="text-align: center;" class="<?php echo $cls; ?>"><?php echo yms_notes_cell($row['notes'], $row['id']); ?></td> |
|
160 |
|
161 <!-- Actions --> |
|
162 <td style="text-align: center;" class="<?php echo $cls; ?>"><?php echo yms_show_actions($row); ?></td> |
|
163 </tr> |
|
164 <?php |
|
165 } |
|
166 ?> |
|
167 |
|
168 </table> |
|
169 </div> |
|
170 |
|
171 <br /><br /> |
|
172 <a href="<?php echo makeUrlNS('Special', 'YMS/Converter'); ?>" onclick="yms_showpage('Converter'); return false;" class="abutton abutton_red icon" |
|
173 style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/application_view_icons.png);"> |
|
174 <?php echo $lang->get('yms_btn_show_converter'); ?> |
|
175 </a> |
|
176 |
|
177 <a href="<?php echo makeUrlNS('Special', 'YMS/Converter'); ?>" onclick="yms_showpage('ShowClientInfo'); return false;" class="abutton abutton_blue icon" |
|
178 style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/show_client_info.png);"> |
|
179 <?php echo $lang->get('yms_btn_show_client_info'); ?> |
|
180 </a> |
|
181 |
|
182 <?php |
|
183 } |
|
184 $db->free_result($q); |
|
185 |
|
186 // close off inner div (yms-keylist) |
|
187 if ( !isset($_GET['ajax'] ) ) |
|
188 echo '</div>'; |
|
189 |
|
190 // Send footer |
|
191 $output->footer(); |
|
192 } |
|
193 |
|
194 // Add key, using AES secret |
|
195 function page_Special_YMS_AddKey() |
|
196 { |
|
197 global $output; |
|
198 global $lang; |
|
199 |
|
200 $output->header(); |
|
201 ?> |
|
202 <h3><?php echo $lang->get('yms_lbl_addkey_heading'); ?></h3> |
|
203 <p><?php echo $lang->get('yms_lbl_addkey_desc'); ?></p> |
|
204 <form action="<?php echo makeUrlNS('Special', 'YMS'); ?>" method="post"> |
|
205 |
|
206 <div class="tblholder"> |
|
207 <table border="0" cellspacing="1" cellspacing="4"> |
|
208 |
|
209 <!-- AES secret --> |
|
210 <tr> |
|
211 <td class="row2"> |
|
212 <?php echo $lang->get('yms_lbl_addkey_field_secret'); ?><br /> |
|
213 <small><?php echo $lang->get('yms_lbl_addkey_field_secret_hint'); ?></small> |
|
214 </td> |
|
215 <td class="row1"> |
|
216 <input type="text" name="add_aes" value="" size="40" /> |
|
217 </td> |
|
218 </tr> |
|
219 |
|
220 <!-- OTP --> |
|
221 <tr> |
|
222 <td class="row2"> |
|
223 <?php echo $lang->get('yms_lbl_addkey_field_otp'); ?> |
|
224 </td> |
|
225 <td class="row1"> |
|
226 <?php echo generate_yubikey_field('add_otp'); ?> |
|
227 </td> |
|
228 </tr> |
|
229 |
|
230 <!-- State --> |
|
231 <tr> |
|
232 <td class="row2"> |
|
233 <?php echo $lang->get('yms_lbl_addkey_field_state'); ?> |
|
234 </td> |
|
235 <td class="row1"> |
|
236 <select name="state"> |
|
237 <option value="active" selected="selected"><?php echo $lang->get('yms_state_active'); ?></option> |
|
238 <option value="inactive"><?php echo $lang->get('yms_state_inactive'); ?></option> |
|
239 </select> |
|
240 </td> |
|
241 </tr> |
|
242 |
|
243 <!-- Any client --> |
|
244 <tr> |
|
245 <td class="row2"> |
|
246 <?php echo $lang->get('yms_lbl_addkey_field_any_client_name'); ?><br /> |
|
247 <small><?php echo $lang->get('yms_lbl_addkey_field_any_client_hint'); ?></small> |
|
248 </td> |
|
249 <td class="row1"> |
|
250 <label> |
|
251 <input type="checkbox" name="any_client" /> |
|
252 <?php echo $lang->get('yms_lbl_addkey_field_any_client'); ?> |
|
253 </label> |
|
254 </td> |
|
255 </tr> |
|
256 |
|
257 <!-- Notes --> |
|
258 <tr> |
|
259 <td class="row2"> |
|
260 <?php echo $lang->get('yms_lbl_addkey_field_notes'); ?> |
|
261 </td> |
|
262 <td class="row1"> |
|
263 <textarea style="font-family: sans-serif; font-size: 9pt;" name="notes" rows="5" cols="40"></textarea> |
|
264 </td> |
|
265 </tr> |
|
266 |
|
267 <!-- Submit --> |
|
268 <tr> |
|
269 <th class="subhead" colspan="2"> |
|
270 <input type="submit" value="<?php echo $lang->get('yms_btn_addkey_submit'); ?>" /> |
|
271 </th> |
|
272 </tr> |
|
273 |
|
274 </table> |
|
275 </div> |
|
276 |
|
277 </form> |
|
278 <?php |
|
279 $output->footer(); |
|
280 } |
|
281 |
|
282 // Add key that's already registered |
|
283 function page_Special_YMS_AddPreregisteredKey() |
|
284 { |
|
285 global $db, $session, $paths, $template, $plugins; // Common objects |
|
286 global $lang, $output; |
|
287 |
|
288 $output->header(); |
|
289 ?> |
|
290 <h3><?php echo $lang->get('yms_lbl_claimkey_heading'); ?></h3> |
|
291 <p><?php echo $lang->get('yms_lbl_claimkey_desc'); ?></p> |
|
292 <form action="<?php echo makeUrlNS('Special', 'YMS'); ?>" method="post"> |
|
293 |
|
294 <div class="tblholder"> |
|
295 <table border="0" cellspacing="1" cellspacing="4"> |
|
296 |
|
297 <!-- OTP --> |
|
298 <tr> |
|
299 <td class="row2"> |
|
300 <?php echo $lang->get('yms_lbl_addkey_field_otp'); ?> |
|
301 </td> |
|
302 <td class="row1"> |
|
303 <?php echo generate_yubikey_field('claim_otp'); ?> |
|
304 </td> |
|
305 </tr> |
|
306 |
|
307 <!-- State --> |
|
308 <tr> |
|
309 <td class="row2"> |
|
310 <?php echo $lang->get('yms_lbl_addkey_field_state'); ?> |
|
311 </td> |
|
312 <td class="row1"> |
|
313 <select name="state"> |
|
314 <option value="active" selected="selected"><?php echo $lang->get('yms_state_active'); ?></option> |
|
315 <option value="inactive"><?php echo $lang->get('yms_state_inactive'); ?></option> |
|
316 </select> |
|
317 </td> |
|
318 </tr> |
|
319 |
|
320 <!-- Any client --> |
|
321 <tr> |
|
322 <td class="row2"> |
|
323 <?php echo $lang->get('yms_lbl_addkey_field_any_client_name'); ?><br /> |
|
324 <small><?php echo $lang->get('yms_lbl_addkey_field_any_client_hint'); ?></small> |
|
325 </td> |
|
326 <td class="row1"> |
|
327 <label> |
|
328 <input type="checkbox" name="any_client" /> |
|
329 <?php echo $lang->get('yms_lbl_addkey_field_any_client'); ?> |
|
330 </label> |
|
331 </td> |
|
332 </tr> |
|
333 |
|
334 <!-- Notes --> |
|
335 <tr> |
|
336 <td class="row2"> |
|
337 <?php echo $lang->get('yms_lbl_addkey_field_notes'); ?> |
|
338 </td> |
|
339 <td class="row1"> |
|
340 <textarea style="font-family: sans-serif; font-size: 9pt;" name="notes" rows="5" cols="40"></textarea> |
|
341 </td> |
|
342 </tr> |
|
343 |
|
344 <?php if ( ($field = getConfig('yms_claim_auth_field', '')) && getConfig('yms_claim_auth_url') ): ?> |
|
345 <!-- Custom field --> |
|
346 <tr> |
|
347 <td class="row2"> |
|
348 <?php echo htmlspecialchars($field); ?> |
|
349 </td> |
|
350 <td class="row1"> |
|
351 <input type="text" name="custom_field" value="" size="30" /> |
|
352 </td> |
|
353 </tr> |
|
354 <?php endif; ?> |
|
355 |
|
356 <!-- Submit --> |
|
357 <tr> |
|
358 <th class="subhead" colspan="2"> |
|
359 <input type="submit" value="<?php echo $lang->get('yms_btn_addkey_submit'); ?>" /> |
|
360 </th> |
|
361 </tr> |
|
362 |
|
363 </table> |
|
364 </div> |
|
365 |
|
366 </form> |
|
367 <?php |
|
368 $output->footer(); |
|
369 } |
|
370 |
|
371 // Show the AES secret for a key |
|
372 function page_Special_YMS_ShowAESKey() |
|
373 { |
|
374 global $db, $session, $paths, $template, $plugins; // Common objects |
|
375 global $lang, $output; |
|
376 |
|
377 $id = intval($paths->getParam(1)); |
|
378 |
|
379 // verify ownership, retrieve key |
|
380 $q = $db->sql_query('SELECT client_id, public_id, aes_secret FROM ' . table_prefix . "yms_yubikeys WHERE id = $id;"); |
|
381 if ( !$q ) |
|
382 $db->_die(); |
|
383 |
|
384 if ( $db->numrows() < 1 ) |
|
385 { |
|
386 die_friendly('no rows', '<p>key not found</p>'); |
|
387 } |
|
388 |
|
389 list($client_id, $public_id, $secret) = $db->fetchrow_num(); |
|
390 $db->free_result(); |
|
391 |
|
392 if ( $client_id !== $session->user_id ) |
|
393 die_friendly($lang->get('etc_access_denied_short'), '<p>' . $lang->get('etc_access_denied') . '</p>'); |
|
394 |
|
395 $output->header(); |
|
396 ?> |
|
397 <div class="tblholder"> |
|
398 <table border="0" cellspacing="1" cellpadding="4"> |
|
399 <tr> |
|
400 <th colspan="2"> |
|
401 <?php echo $lang->get('yms_showaes_th', array('public_id' => yms_modhex_encode($public_id))); ?> |
|
402 </th> |
|
403 </tr> |
|
404 |
|
405 <!-- hex --> |
|
406 <tr> |
|
407 <td class="row2" style="width: 50%;"> |
|
408 <?php echo $lang->get('yms_showaes_lbl_hex'); ?> |
|
409 </td> |
|
410 <td class="row1"> |
|
411 <?php echo $secret; ?> |
|
412 </td> |
|
413 </tr> |
|
414 |
|
415 <!-- modhex --> |
|
416 <tr> |
|
417 <td class="row2"> |
|
418 <?php echo $lang->get('yms_showaes_lbl_modhex'); ?> |
|
419 </td> |
|
420 <td class="row1"> |
|
421 <?php echo yms_modhex_encode($secret); ?> |
|
422 </td> |
|
423 </tr> |
|
424 |
|
425 <!-- base64 --> |
|
426 <tr> |
|
427 <td class="row2"> |
|
428 <?php echo $lang->get('yms_showaes_lbl_base64'); ?> |
|
429 </td> |
|
430 <td class="row1"> |
|
431 <?php echo base64_encode(yms_tobinary($secret)); ?> |
|
432 </td> |
|
433 </tr> |
|
434 |
|
435 </table> |
|
436 </div> |
|
437 <?php |
|
438 $output->footer(); |
|
439 } |
|
440 |
|
441 // show the user's API key and client ID |
|
442 function page_Special_YMS_ShowClientInfo() |
|
443 { |
|
444 global $db, $session, $paths, $template, $plugins; // Common objects |
|
445 global $lang, $output; |
|
446 |
|
447 $q = $db->sql_query('SELECT apikey FROM ' . table_prefix . "yms_clients WHERE id = {$session->user_id};"); |
|
448 if ( !$q ) |
|
449 $db->_die(); |
|
450 |
|
451 list($api_key) = $db->fetchrow_num(); |
|
452 $db->free_result(); |
|
453 |
|
454 $api_key = yms_tobinary($api_key); |
|
455 |
|
456 $output->header(); |
|
457 ?> |
|
458 <div class="tblholder"> |
|
459 <table border="0" cellspacing="1" cellpadding="4"> |
|
460 |
|
461 <tr> |
|
462 <th colspan="2"><?php echo $lang->get('yms_th_client_id'); ?></th> |
|
463 </tr> |
|
464 |
|
465 <tr> |
|
466 <td class="row2"><?php echo $lang->get('yms_lbl_client_id'); ?></td> |
|
467 <td class="row1"><?php echo strval($session->user_id); ?></td> |
|
468 </tr> |
|
469 |
|
470 <tr> |
|
471 <th colspan="2"><?php echo $lang->get('yms_th_api_key'); ?></th> |
|
472 </tr> |
|
473 |
|
474 <tr> |
|
475 <td class="row2"><?php echo $lang->get('yms_showaes_lbl_hex'); ?></td> |
|
476 <td class="row1"><?php echo yms_hex_encode($api_key); ?></td> |
|
477 </tr> |
|
478 |
|
479 <tr> |
|
480 <td class="row2"><?php echo $lang->get('yms_showaes_lbl_modhex'); ?></td> |
|
481 <td class="row1"><?php echo yms_modhex_encode($api_key); ?></td> |
|
482 </tr> |
|
483 |
|
484 <tr> |
|
485 <td class="row2"><?php echo $lang->get('yms_showaes_lbl_base64'); ?></td> |
|
486 <td class="row1"><?php echo base64_encode($api_key); ?></td> |
|
487 </tr> |
|
488 |
|
489 </table> |
|
490 </div> |
|
491 <?php |
|
492 $output->footer(); |
|
493 } |
|
494 |
|
495 // Converter between different binary encodings |
|
496 function page_Special_YMS_Converter() |
|
497 { |
|
498 global $db, $session, $paths, $template, $plugins; // Common objects |
|
499 global $lang, $output; |
|
500 |
|
501 $output->header(); |
|
502 |
|
503 if ( isset($_POST['value']) ) |
|
504 { |
|
505 switch($_POST['format']) |
|
506 { |
|
507 case 'auto': |
|
508 default: |
|
509 $binary = yms_tobinary($_POST['value']); |
|
510 break; |
|
511 case 'hex': |
|
512 $_POST['value'] = str_replace(" ", '', $_POST['value']); |
|
513 $binary = yms_hex_decode($_POST['value']); |
|
514 break; |
|
515 case 'modhex': |
|
516 $binary = yms_hex_decode(yms_modhex_decode($_POST['value'])); |
|
517 break; |
|
518 case 'base64': |
|
519 $binary = base64_decode($_POST['value']); |
|
520 break; |
|
521 } |
|
522 |
|
523 if ( empty($binary) ) |
|
524 { |
|
525 echo '<div class="error-box">' . $lang->get('yms_conv_err_invalid_string') . '</div>'; |
|
526 } |
|
527 else |
|
528 { |
|
529 ?> |
|
530 <div class="tblholder"> |
|
531 <table border="0" cellspacing="1" cellpadding="4"> |
|
532 |
|
533 <tr> |
|
534 <th colspan="2"><?php echo $lang->get('yms_th_converted_value'); ?></th> |
|
535 </tr> |
|
536 |
|
537 <tr> |
|
538 <td class="row2"><?php echo $lang->get('yms_showaes_lbl_hex'); ?></td> |
|
539 <td class="row1"><?php echo yms_hex_encode($binary); ?></td> |
|
540 </tr> |
|
541 |
|
542 <tr> |
|
543 <td class="row2"><?php echo $lang->get('yms_showaes_lbl_modhex'); ?></td> |
|
544 <td class="row1"><?php echo yms_modhex_encode($binary); ?></td> |
|
545 </tr> |
|
546 |
|
547 <tr> |
|
548 <td class="row2"><?php echo $lang->get('yms_showaes_lbl_base64'); ?></td> |
|
549 <td class="row1"><?php echo base64_encode($binary); ?></td> |
|
550 </tr> |
|
551 |
|
552 </table> |
|
553 </div> |
|
554 <?php |
|
555 } |
|
556 } |
|
557 |
|
558 ?> |
|
559 <form method="post" class="submit_to_self" action="<?php echo makeUrl($paths->fullpage); ?>"> |
|
560 |
|
561 <div class="tblholder"> |
|
562 <table border="0" cellspacing="1" cellpadding="4"> |
|
563 |
|
564 <tr> |
|
565 <th colspan="2"><?php echo $lang->get('yms_th_converter'); ?></th> |
|
566 </tr> |
|
567 |
|
568 <tr> |
|
569 <td class="row2" style="width: 30%;"><?php echo $lang->get('yms_conv_lbl_value'); ?></td> |
|
570 <td class="row1"><input type="text" name="value" size="60" /></td> |
|
571 </tr> |
|
572 |
|
573 <tr> |
|
574 <td class="row2" style="width: 30%;"><?php echo $lang->get('yms_conv_lbl_format'); ?></td> |
|
575 <td class="row1"> |
|
576 <?php |
|
577 foreach ( array('auto', 'hex', 'modhex', 'base64') as $i => $fmt ) |
|
578 { |
|
579 echo '<label><input type="radio" name="format" value="' . $fmt . '" '; |
|
580 if ( ( isset($_POST['format']) && $_POST['format'] === $fmt ) || ( !isset($_POST['format']) && $i == 0 ) ) |
|
581 echo 'checked="checked" '; |
|
582 |
|
583 echo '/> '; |
|
584 echo $lang->get("yms_conv_lbl_format_$fmt"); |
|
585 echo "</label>\n "; |
|
586 } |
|
587 ?> |
|
588 </td> |
|
589 </tr> |
|
590 |
|
591 <tr> |
|
592 <th class="subhead" colspan="2"> |
|
593 <input type="submit" value="<?php echo $lang->get('yms_conv_btn_submit'); ?>" /> |
|
594 </th> |
|
595 </tr> |
|
596 |
|
597 </table> |
|
598 </div> |
|
599 |
|
600 </form> |
|
601 <?php |
|
602 |
|
603 $output->footer(); |
|
604 } |
|
605 |
|
606 function page_Special_YMS_AjaxToggleState() |
|
607 { |
|
608 global $db, $session, $paths, $template, $plugins; // Common objects |
|
609 |
|
610 $id = intval($_POST['id']); |
|
611 if ( $_POST['state'] === 'active' ) |
|
612 $expr = 'flags | ' . YMS_ENABLED; |
|
613 else |
|
614 $expr = 'flags & ~' . YMS_ENABLED; |
|
615 |
|
616 $q = $db->sql_query('UPDATE ' . table_prefix . "yms_yubikeys SET flags = $expr WHERE id = $id AND client_id = {$session->user_id};"); |
|
617 if ( !$q ) |
|
618 $db->die_json(); |
|
619 |
|
620 if ( $db->sql_affectedrows() < 1 ) |
|
621 echo 'no affected rows; not '; |
|
622 |
|
623 echo 'ok'; |
|
624 } |
|
625 |
|
626 function page_Special_YMS_AjaxNotes() |
|
627 { |
|
628 global $db, $session, $paths, $template, $plugins; // Common objects |
|
629 |
|
630 if ( isset($_POST['get']) ) |
|
631 { |
|
632 $id = intval($_POST['get']); |
|
633 $q = $db->sql_query('SELECT notes FROM ' . table_prefix . "yms_yubikeys WHERE id = $id AND client_id = {$session->user_id};"); |
|
634 if ( !$q ) |
|
635 $db->_die(); |
|
636 if ( $db->numrows() < 1 ) |
|
637 { |
|
638 echo "key not found"; |
|
639 } |
|
640 else |
|
641 { |
|
642 list($note) = $db->fetchrow_num(); |
|
643 echo $note; |
|
644 } |
|
645 $db->free_result(); |
|
646 } |
|
647 else if ( isset($_POST['save']) ) |
|
648 { |
|
649 $id = intval($_POST['save']); |
|
650 $note = trim($_POST['note']); |
|
651 $note = $db->escape($note); |
|
652 $q = $db->sql_query('UPDATE ' . table_prefix . "yms_yubikeys SET notes = '$note' WHERE id = $id AND client_id = {$session->user_id};"); |
|
653 if ( !$q ) |
|
654 $db->die_json(); |
|
655 |
|
656 echo 'ok'; |
|
657 } |
|
658 } |
|
659 |
|
660 // Add key, using just an OTP |
|
661 // Requires the key to be in the database as client ID 0 |
|
662 |
|
663 // Client creation |
|
664 function page_Special_YMSCreateClient() |
|
665 { |
|
666 global $db, $session, $paths, $template, $plugins; // Common objects |
|
667 global $lang; |
|
668 global $output; |
|
669 |
|
670 // Require re-auth? |
|
671 if ( $session->auth_level < USER_LEVEL_CHPREF && getConfig('yms_require_reauth', 1) == 1 ) |
|
672 { |
|
673 redirect(makeUrlNS('Special', "Login/$paths->fullpage", 'level=' . USER_LEVEL_CHPREF), '', '', 0); |
|
674 } |
|
675 |
|
676 // Check for Yubikey plugin |
|
677 if ( !function_exists('yubikey_validate_otp') ) |
|
678 { |
|
679 die_friendly($lang->get('yms_err_yubikey_plugin_missing_title'), '<p>' . $lang->get('yms_err_yubikey_plugin_missing_body') . '</p>'); |
|
680 } |
|
681 |
|
682 // Does the client exist? |
|
683 $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . "yms_clients WHERE id = {$session->user_id};"); |
|
684 if ( !$q ) |
|
685 $db->_die(); |
|
686 |
|
687 $client_exists = $db->numrows(); |
|
688 $db->free_result(); |
|
689 |
|
690 if ( $client_exists ) |
|
691 { |
|
692 die_friendly($lang->get('yms_err_client_exists_title'), '<p>' . $lang->get('yms_err_client_exists_body') . '</p>'); |
|
693 } |
|
694 |
|
695 $template->add_header('<link rel="stylesheet" type="text/css" href="' . scriptPath . '/plugins/yms/styles.css" />'); |
|
696 $output->header(); |
|
697 |
|
698 if ( isset($_POST['register_client']) ) |
|
699 { |
|
700 // register the client |
|
701 // SHA1 key length: 160 bits |
|
702 $api_key = base64_encode(AESCrypt::randkey(160 / 8)); |
|
703 $client_id = $session->user_id; |
|
704 |
|
705 $q = $db->sql_query('INSERT INTO ' . table_prefix . "yms_clients(id, apikey) VALUES ($client_id, '$api_key');"); |
|
706 if ( !$q ) |
|
707 $db->_die(); |
|
708 |
|
709 $validate_url = makeUrlComplete('Special', 'YubikeyValidate'); |
|
710 $validate_url = preg_replace('/[?&]auth=[0-9a-f]+/', '', $validate_url); |
|
711 |
|
712 ?> |
|
713 <h3><?php echo $lang->get('yms_register_msg_success_title'); ?></h3> |
|
714 <?php echo $lang->get('yms_register_msg_success_body', array( |
|
715 'yms_link' => makeUrlNS('Special', 'YMS'), |
|
716 'client_id' => $client_id, |
|
717 'api_key' => $api_key, |
|
718 'validate_url' => $validate_url |
|
719 )); |
|
720 } |
|
721 else |
|
722 { |
|
723 // confirmation page |
|
724 ?> |
|
725 <form action="<?php echo makeUrlNS('Special', 'YMSCreateClient'); ?>" method="post"> |
|
726 <h3><?php echo $lang->get('yms_register_confirm_title'); ?></h3> |
|
727 <p><?php echo $lang->get('yms_register_confirm_body'); ?></p> |
|
728 <p> |
|
729 <input type="submit" style="font-weight: bold;" name="register_client" value="<?php echo $lang->get('yms_register_btn_submit'); ?>" /> |
|
730 <input type="submit" name="cancel" value="<?php echo $lang->get('etc_cancel'); ?>" /> |
|
731 </p> |
|
732 </form> |
|
733 <?php |
|
734 } |
|
735 |
|
736 $output->footer(); |
|
737 } |
|
738 |
|
739 // Generic response function |
|
740 // Processing functions return either true or a string containing an error message. This |
|
741 // takes that return, and sends a response through the appropriate channel, while allowing |
|
742 // shared backend functions. |
|
743 |
|
744 function yms_send_response($success_string, $result) |
|
745 { |
|
746 global $lang, $output; |
|
747 |
|
748 if ( $result === true ) |
|
749 { |
|
750 if ( isset($_GET['ajax']) ) |
|
751 { |
|
752 yms_json_response(array( |
|
753 'mode' => 'success', |
|
754 'message' => $lang->get($success_string) |
|
755 )); |
|
756 } |
|
757 else |
|
758 { |
|
759 $output->add_after_header( |
|
760 '<div class="info-box">' . $lang->get($success_string) . '</div>' |
|
761 ); |
|
762 } |
|
763 } |
|
764 else |
|
765 { |
|
766 if ( isset($_GET['ajax']) ) |
|
767 { |
|
768 yms_json_response(array( |
|
769 'mode' => 'error', |
|
770 'error' => $lang->get($result) |
|
771 )); |
|
772 } |
|
773 else |
|
774 { |
|
775 $output->add_after_header( |
|
776 '<div class="error-box">' . $lang->get($result) . '</div>' |
|
777 ); |
|
778 } |
|
779 } |
|
780 } |
|
781 |
|
782 function yms_json_response($response) |
|
783 { |
|
784 global $db, $session, $paths, $template, $plugins; // Common objects |
|
785 |
|
786 header('Content-type: application/json'); |
|
787 echo enano_json_encode($response); |
|
788 |
|
789 $db->close(); |
|
790 exit; |
|
791 } |
|
792 |
|
793 function yms_date($ts) |
|
794 { |
|
795 return enano_date('Y-m-d H:m:i', $ts); |
|
796 } |
|
797 |
|
798 function yms_state_indicator($flags, $id) |
|
799 { |
|
800 global $lang; |
|
801 return $flags & YMS_ENABLED ? |
|
802 '<span onclick="yms_toggle_state(this, ' . $id . ');" class="yms-enabled">' . $lang->get('yms_state_active') . '</span>' : |
|
803 '<span onclick="yms_toggle_state(this, ' . $id . ');" class="yms-disabled">' . $lang->get('yms_state_inactive') . '</span>'; |
|
804 } |
|
805 |
|
806 function yms_notes_cell($notes, $id) |
|
807 { |
|
808 global $lang; |
|
809 $notes = trim($notes); |
|
810 if ( empty($notes) ) |
|
811 { |
|
812 $img = 'note_delete.png'; |
|
813 $str = $lang->get('yms_btn_note_create'); |
|
814 } |
|
815 else |
|
816 { |
|
817 $img = 'note.png'; |
|
818 $str = $lang->get('yms_btn_note_view'); |
|
819 } |
|
820 echo '<a href="#" onclick="yms_show_notes(this, '.$id.'); return false;" title="' . $str . '"><img alt="' . $str . '" src="' . scriptPath . '/plugins/yms/icons/' . $img . '" /></a>'; |
|
821 |
|
822 if ( !empty($notes) ) |
|
823 { |
|
824 echo ' '; |
|
825 if ( strlen($notes) > 15 ) |
|
826 echo htmlspecialchars(substr($notes, 0, 12)) . '...'; |
|
827 else |
|
828 echo htmlspecialchars($notes); |
|
829 } |
|
830 } |
|
831 |
|
832 function yms_show_actions($row) |
|
833 { |
|
834 global $lang; |
|
835 |
|
836 // Show AES secret |
|
837 ?> |
|
838 <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;"> |
|
839 <img alt="<?php echo $lang->get('yms_btn_show_aes'); ?>" src="<?php echo scriptPath; ?>/plugins/yms/icons/key_go.png" /> |
|
840 </a> |
|
841 <?php |
|
842 } |