101 $enabled = true; |
101 $enabled = true; |
102 } |
102 } |
103 |
103 |
104 $result = yms_add_yubikey($_POST['add_aes'], $_POST['add_otp'], $client_id, $enabled, $any_client, $notes); |
104 $result = yms_add_yubikey($_POST['add_aes'], $_POST['add_otp'], $client_id, $enabled, $any_client, $notes); |
105 yms_send_response('yms_msg_addkey_success', $result); |
105 yms_send_response('yms_msg_addkey_success', $result); |
|
106 } |
|
107 else if ( isset($_POST['csv']) ) |
|
108 { |
|
109 $csv = explode("\n", trim($_POST['csv'])); |
|
110 |
|
111 $errors = array(); |
|
112 |
|
113 // first line: header |
|
114 $head = str_getcsv($csv[0]); |
|
115 |
|
116 // column check: aes_secret |
|
117 if ( !in_array('aes_secret', $head) ) |
|
118 { |
|
119 $errors[] = $lang->get('yms_err_add_batch_missing_aes_key'); |
|
120 } |
|
121 |
|
122 // column check: otp, public_id and private_id |
|
123 if ( !in_array('otp', $head) ) |
|
124 { |
|
125 if ( !in_array('public_id', $head) || !in_array('private_id', $head) ) |
|
126 { |
|
127 $errors[] = $lang->get('yms_err_add_batch_missing_id'); |
|
128 } |
|
129 } |
|
130 |
|
131 if ( !empty($errors) ) |
|
132 { |
|
133 yms_send_response(false, '<ul><li>' . implode('</li><li>', $errors) . '</li></ul>'); |
|
134 } |
|
135 |
|
136 // we are good to start processing |
|
137 $db->transaction_begin(); |
|
138 for ( $i = 1; $i < count($csv); $i++ ) |
|
139 { |
|
140 $line = str_getcsv($csv[$i]); |
|
141 |
|
142 // ensure column count == row count |
|
143 if ( count($line) !== count($head) ) |
|
144 { |
|
145 $errors[] = $lang->get('yms_err_add_batch_bad_row_count', array('line' => $i)); |
|
146 continue; |
|
147 } |
|
148 |
|
149 // remap line |
|
150 foreach ( $head as $j => $col ) |
|
151 { |
|
152 $line[$col] =& $line[$j]; |
|
153 } |
|
154 |
|
155 // initialize row |
|
156 $row = array( |
|
157 'client_id' => $yms_client_id, |
|
158 'aes_secret' => yms_hex_encode(yms_tobinary($line['aes_secret'])), |
|
159 'session_count' => 0, |
|
160 'token_count' => 0, |
|
161 'create_time' => time(), |
|
162 'token_time' => 0, |
|
163 'flags' => 0, |
|
164 'notes' => '' |
|
165 ); |
|
166 |
|
167 if ( !preg_match('/^[0-9a-f]{32}$/', $row['aes_secret']) ) |
|
168 { |
|
169 $errors[] = $lang->get('yms_err_add_batch_aes_secret', array('line' => $i)); |
|
170 continue; |
|
171 } |
|
172 |
|
173 // do we have an OTP? |
|
174 if ( isset($line['otp']) ) |
|
175 { |
|
176 // yes, decode it |
|
177 $otp = yms_decode_otp($line['otp'], $line['aes_secret']); |
|
178 if ( $otp === false ) |
|
179 { |
|
180 $errors[] = $lang->get('yms_err_add_batch_bad_otp', array('line' => $i)); |
|
181 continue; |
|
182 } |
|
183 |
|
184 if ( !$otp['crc_good'] ) |
|
185 { |
|
186 $errors[] = $lang->get('yms_err_add_batch_bad_otp', array('line' => $i)); |
|
187 continue; |
|
188 } |
|
189 |
|
190 $row['public_id'] = $otp['publicid']; |
|
191 $row['private_id'] = $otp['privateid']; |
|
192 $row['session_count'] = $otp['session']; |
|
193 $row['token_count'] = $otp['count']; |
|
194 $row['token_time'] = $otp['timestamp']; |
|
195 } |
|
196 |
|
197 // public and private ID |
|
198 foreach ( array('public_id', 'private_id') as $col ) |
|
199 { |
|
200 if ( !empty($line[$col]) ) |
|
201 { |
|
202 $row[$col] = yms_hex_encode(yms_tobinary($line[$col])); |
|
203 } |
|
204 if ( !isset($row[$col]) || !preg_match('/^[0-9a-f]{12}$/', $row[$col]) ) |
|
205 { |
|
206 $errors[] = $lang->get("yms_err_add_batch_bad_$col", array('line' => $i)); |
|
207 continue 2; |
|
208 } |
|
209 } |
|
210 |
|
211 // session count, token count and timestamp |
|
212 foreach ( array('session_count', 'token_count', 'token_time') as $col ) |
|
213 { |
|
214 if ( !empty($line[$col]) ) |
|
215 { |
|
216 $row[$col] = intval($line[$col]); |
|
217 } |
|
218 } |
|
219 |
|
220 // notes |
|
221 if ( isset($line['notes']) ) |
|
222 { |
|
223 $row['notes'] = trim($line['notes']); |
|
224 } |
|
225 |
|
226 // lifecycle state |
|
227 if ( isset($line['lifecycle_state']) ) |
|
228 { |
|
229 if ( !in_array($line['lifecycle_state'], array('active', 'inactive')) ) |
|
230 { |
|
231 $errors[] = $lang->get('yms_err_add_batch_bad_lifecycle_state', array('line' => $i)); |
|
232 continue; |
|
233 } |
|
234 |
|
235 if ( $line['lifecycle_state'] === 'active' ) |
|
236 { |
|
237 $row['flags'] |= YMS_ENABLED; |
|
238 } |
|
239 } |
|
240 else |
|
241 { |
|
242 // default to active |
|
243 $row['flags'] |= YMS_ENABLED; |
|
244 } |
|
245 |
|
246 // global access |
|
247 if ( isset($line['access']) ) |
|
248 { |
|
249 if ( !in_array($line['access'], array('global', 'restricted')) ) |
|
250 { |
|
251 $errors[] = $lang->get('yms_err_add_batch_bad_access', array('line' => $i)); |
|
252 continue; |
|
253 } |
|
254 |
|
255 if ( $line['access'] === 'global' ) |
|
256 { |
|
257 $row['flags'] |= YMS_ANY_CLIENT; |
|
258 } |
|
259 } |
|
260 |
|
261 // duplicate key check |
|
262 $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . "yms_yubikeys WHERE public_id = '{$row['public_id']}';"); |
|
263 if ( $db->numrows() > 0 ) |
|
264 { |
|
265 $errors[] = $lang->get('yms_err_add_batch_duplicate', array('line' => $i, 'public_id' => $row['public_id'])); |
|
266 continue; |
|
267 } |
|
268 |
|
269 // build query |
|
270 $cols = implode(', ', array_keys($row)); |
|
271 |
|
272 foreach ( $row as &$cell ) |
|
273 { |
|
274 if ( is_string($cell) ) |
|
275 { |
|
276 $cell = "'" . $db->escape($cell) . "'"; |
|
277 } |
|
278 } |
|
279 unset($cell); |
|
280 |
|
281 $query = sprintf("INSERT INTO %syms_yubikeys ( %s ) VALUES ( %s );", |
|
282 table_prefix, |
|
283 $cols, |
|
284 implode(', ', $row) |
|
285 ); |
|
286 |
|
287 // insert it! |
|
288 $q = $db->sql_query($query); |
|
289 if ( $q ) |
|
290 { |
|
291 $errors[] = $lang->get('yms_err_add_batch_success', array('line' => $i, 'public_id' => $row['public_id'])); |
|
292 } |
|
293 else |
|
294 { |
|
295 $errors[] = $lang->get('yms_err_add_batch_query', array('line' => $i, 'public_id' => $row['public_id'], 'error' => $db->sql_error())); |
|
296 } |
|
297 } |
|
298 $db->transaction_commit(); |
|
299 |
|
300 yms_send_response('<p><strong>' . $lang->get('yms_lbl_add_batch_success_head') . '</strong></p><ul><li>' . implode('</li><li>', $errors) . '</li></ul>', true); |
106 } |
301 } |
107 else if ( isset($_POST['claim_otp']) && getConfig('yms_claim_enable', 0) == 1 ) |
302 else if ( isset($_POST['claim_otp']) && getConfig('yms_claim_enable', 0) == 1 ) |
108 { |
303 { |
109 // do we need to validate a custom field? |
304 // do we need to validate a custom field? |
110 if ( ($url = getConfig('yms_claim_auth_url')) && getConfig('yms_claim_auth_field') && getConfig('yms_claim_auth_enable', 0) == 1 ) |
305 if ( ($url = getConfig('yms_claim_auth_url')) && getConfig('yms_claim_auth_field') && getConfig('yms_claim_auth_enable', 0) == 1 ) |
174 ?> |
369 ?> |
175 <div class="yms-buttons"> |
370 <div class="yms-buttons"> |
176 <a class="abutton abutton_green icon" style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/key_add.png);" |
371 <a class="abutton abutton_green icon" style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/key_add.png);" |
177 href="<?php echo makeUrlNS('Special', 'YMS/AddKey'); ?>" onclick="yms_showpage('AddKey'); return false;"> |
372 href="<?php echo makeUrlNS('Special', 'YMS/AddKey'); ?>" onclick="yms_showpage('AddKey'); return false;"> |
178 <?php echo $lang->get('yms_btn_add_key'); ?> |
373 <?php echo $lang->get('yms_btn_add_key'); ?> |
|
374 </a> |
|
375 <a class="abutton icon" style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/key_add.png);" |
|
376 href="<?php echo makeUrlNS('Special', 'YMS/AddKeyBatch'); ?>" onclick="yms_showpage('AddKeyBatch'); return false;"> |
|
377 <?php echo $lang->get('yms_btn_add_batch'); ?> |
179 </a> |
378 </a> |
180 <?php if ( getConfig('yms_claim_enable', 0) == 1 && $yms_client_id > 0 ): ?> |
379 <?php if ( getConfig('yms_claim_enable', 0) == 1 && $yms_client_id > 0 ): ?> |
181 <a class="abutton abutton_blue icon" style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/key_add.png);" |
380 <a class="abutton abutton_blue icon" style="background-image: url(<?php echo scriptPath; ?>/plugins/yms/icons/key_add.png);" |
182 href="<?php echo makeUrlNS('Special', 'YMS/AddPreregisteredKey'); ?>" onclick="yms_showpage('AddPreregisteredKey'); return false;"> |
381 href="<?php echo makeUrlNS('Special', 'YMS/AddPreregisteredKey'); ?>" onclick="yms_showpage('AddPreregisteredKey'); return false;"> |
183 <?php echo $lang->get('yms_btn_add_key_preregistered'); ?> |
382 <?php echo $lang->get('yms_btn_add_key_preregistered'); ?> |
386 </form> |
585 </form> |
387 <?php |
586 <?php |
388 $output->footer(); |
587 $output->footer(); |
389 } |
588 } |
390 |
589 |
|
590 // Add multiple Yubikeys by uploading a CSV |
|
591 function page_Special_YMS_AddKeyBatch() |
|
592 { |
|
593 global $db, $session, $paths, $template, $plugins; // Common objects |
|
594 global $lang, $output; |
|
595 |
|
596 $output->add_after_header('<div class="breadcrumbs"> |
|
597 <a href="' . makeUrlNS('Special', 'YMS') . '">' . $lang->get('yms_specialpage_yms') . '</a> » |
|
598 ' . $lang->get('yms_btn_add_batch') . ' |
|
599 </div>'); |
|
600 |
|
601 $output->header(); |
|
602 ?> |
|
603 |
|
604 <h3><?php echo $lang->get('yms_lbl_add_batch_heading'); ?></h3> |
|
605 <?php echo $lang->get('yms_lbl_add_batch_desc'); ?> |
|
606 |
|
607 <form action="<?php echo makeUrlNS('Special', 'YMS'); ?>" method="post"> |
|
608 |
|
609 <div class="tblholder"> |
|
610 <table border="0" cellspacing="1" cellspacing="4"> |
|
611 <!-- CSV paste --> |
|
612 <tr> |
|
613 <td class="row2"> |
|
614 <?php echo $lang->get('yms_lbl_add_batch_field_csv'); ?><br /> |
|
615 <small><?php echo $lang->get('yms_lbl_add_batch_field_csv_hint'); ?></small> |
|
616 </td> |
|
617 <td class="row1"> |
|
618 <textarea name="csv" rows="8" cols="60"></textarea> |
|
619 </td> |
|
620 </tr> |
|
621 |
|
622 <!-- Submit --> |
|
623 <tr> |
|
624 <th class="subhead" colspan="2"> |
|
625 <input type="submit" value="<?php echo $lang->get('yms_btn_add_batch_submit'); ?>" /> |
|
626 </th> |
|
627 </tr> |
|
628 </table> |
|
629 </div> |
|
630 |
|
631 </form> |
|
632 |
|
633 <?php |
|
634 $output->footer(); |
|
635 } |
|
636 |
391 // Add key, using just an OTP |
637 // Add key, using just an OTP |
392 // Requires the key to be in the database as client ID 0 |
638 // Requires the key to be in the database as client ID 0 |
393 function page_Special_YMS_AddPreregisteredKey() |
639 function page_Special_YMS_AddPreregisteredKey() |
394 { |
640 { |
395 global $db, $session, $paths, $template, $plugins; // Common objects |
641 global $db, $session, $paths, $template, $plugins; // Common objects |