Branch data Line data Source code
1 : : /* crypto/ui/ui_lib.c -*- mode:C; c-file-style: "eay" -*- */
2 : : /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
3 : : * project 2001.
4 : : */
5 : : /* ====================================================================
6 : : * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
7 : : *
8 : : * Redistribution and use in source and binary forms, with or without
9 : : * modification, are permitted provided that the following conditions
10 : : * are met:
11 : : *
12 : : * 1. Redistributions of source code must retain the above copyright
13 : : * notice, this list of conditions and the following disclaimer.
14 : : *
15 : : * 2. Redistributions in binary form must reproduce the above copyright
16 : : * notice, this list of conditions and the following disclaimer in
17 : : * the documentation and/or other materials provided with the
18 : : * distribution.
19 : : *
20 : : * 3. All advertising materials mentioning features or use of this
21 : : * software must display the following acknowledgment:
22 : : * "This product includes software developed by the OpenSSL Project
23 : : * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24 : : *
25 : : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 : : * endorse or promote products derived from this software without
27 : : * prior written permission. For written permission, please contact
28 : : * openssl-core@openssl.org.
29 : : *
30 : : * 5. Products derived from this software may not be called "OpenSSL"
31 : : * nor may "OpenSSL" appear in their names without prior written
32 : : * permission of the OpenSSL Project.
33 : : *
34 : : * 6. Redistributions of any form whatsoever must retain the following
35 : : * acknowledgment:
36 : : * "This product includes software developed by the OpenSSL Project
37 : : * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 : : *
39 : : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 : : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 : : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 : : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 : : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 : : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 : : * OF THE POSSIBILITY OF SUCH DAMAGE.
51 : : * ====================================================================
52 : : *
53 : : * This product includes cryptographic software written by Eric Young
54 : : * (eay@cryptsoft.com). This product includes software written by Tim
55 : : * Hudson (tjh@cryptsoft.com).
56 : : *
57 : : */
58 : :
59 : : #include <string.h>
60 : : #include "cryptlib.h"
61 : : #include <openssl/e_os2.h>
62 : : #include <openssl/buffer.h>
63 : : #include <openssl/ui.h>
64 : : #include <openssl/err.h>
65 : : #include "ui_locl.h"
66 : :
67 : : IMPLEMENT_STACK_OF(UI_STRING_ST)
68 : :
69 : : static const UI_METHOD *default_UI_meth=NULL;
70 : :
71 : 0 : UI *UI_new(void)
72 : : {
73 : 0 : return(UI_new_method(NULL));
74 : : }
75 : :
76 : 0 : UI *UI_new_method(const UI_METHOD *method)
77 : : {
78 : : UI *ret;
79 : :
80 : 0 : ret=(UI *)OPENSSL_malloc(sizeof(UI));
81 [ # # ]: 0 : if (ret == NULL)
82 : : {
83 : 0 : UIerr(UI_F_UI_NEW_METHOD,ERR_R_MALLOC_FAILURE);
84 : 0 : return NULL;
85 : : }
86 [ # # ]: 0 : if (method == NULL)
87 : 0 : ret->meth=UI_get_default_method();
88 : : else
89 : 0 : ret->meth=method;
90 : :
91 : 0 : ret->strings=NULL;
92 : 0 : ret->user_data=NULL;
93 : 0 : ret->flags=0;
94 : 0 : CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data);
95 : 0 : return ret;
96 : : }
97 : :
98 : 0 : static void free_string(UI_STRING *uis)
99 : : {
100 [ # # ]: 0 : if (uis->flags & OUT_STRING_FREEABLE)
101 : : {
102 : 0 : OPENSSL_free((char *)uis->out_string);
103 [ # # ]: 0 : switch(uis->type)
104 : : {
105 : : case UIT_BOOLEAN:
106 : 0 : OPENSSL_free((char *)uis->_.boolean_data.action_desc);
107 : 0 : OPENSSL_free((char *)uis->_.boolean_data.ok_chars);
108 : 0 : OPENSSL_free((char *)uis->_.boolean_data.cancel_chars);
109 : 0 : break;
110 : : default:
111 : : break;
112 : : }
113 : : }
114 : 0 : OPENSSL_free(uis);
115 : 0 : }
116 : :
117 : 0 : void UI_free(UI *ui)
118 : : {
119 [ # # ]: 0 : if (ui == NULL)
120 : 0 : return;
121 : 0 : sk_UI_STRING_pop_free(ui->strings,free_string);
122 : 0 : CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data);
123 : 0 : OPENSSL_free(ui);
124 : : }
125 : :
126 : 0 : static int allocate_string_stack(UI *ui)
127 : : {
128 [ # # ]: 0 : if (ui->strings == NULL)
129 : : {
130 : 0 : ui->strings=sk_UI_STRING_new_null();
131 [ # # ]: 0 : if (ui->strings == NULL)
132 : : {
133 : : return -1;
134 : : }
135 : : }
136 : : return 0;
137 : : }
138 : :
139 : 0 : static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt,
140 : : int prompt_freeable, enum UI_string_types type, int input_flags,
141 : : char *result_buf)
142 : : {
143 : 0 : UI_STRING *ret = NULL;
144 : :
145 [ # # ]: 0 : if (prompt == NULL)
146 : : {
147 : 0 : UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,ERR_R_PASSED_NULL_PARAMETER);
148 : : }
149 [ # # ]: 0 : else if ((type == UIT_PROMPT || type == UIT_VERIFY
150 [ # # ]: 0 : || type == UIT_BOOLEAN) && result_buf == NULL)
151 : : {
152 : 0 : UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,UI_R_NO_RESULT_BUFFER);
153 : : }
154 [ # # ]: 0 : else if ((ret = (UI_STRING *)OPENSSL_malloc(sizeof(UI_STRING))))
155 : : {
156 : 0 : ret->out_string=prompt;
157 : 0 : ret->flags=prompt_freeable ? OUT_STRING_FREEABLE : 0;
158 : 0 : ret->input_flags=input_flags;
159 : 0 : ret->type=type;
160 : 0 : ret->result_buf=result_buf;
161 : : }
162 : 0 : return ret;
163 : : }
164 : :
165 : 0 : static int general_allocate_string(UI *ui, const char *prompt,
166 : : int prompt_freeable, enum UI_string_types type, int input_flags,
167 : : char *result_buf, int minsize, int maxsize, const char *test_buf)
168 : : {
169 : 0 : int ret = -1;
170 : 0 : UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
171 : : type, input_flags, result_buf);
172 : :
173 [ # # ]: 0 : if (s)
174 : : {
175 [ # # ]: 0 : if (allocate_string_stack(ui) >= 0)
176 : : {
177 : 0 : s->_.string_data.result_minsize=minsize;
178 : 0 : s->_.string_data.result_maxsize=maxsize;
179 : 0 : s->_.string_data.test_buf=test_buf;
180 : 0 : ret=sk_UI_STRING_push(ui->strings, s);
181 : : /* sk_push() returns 0 on error. Let's addapt that */
182 [ # # ]: 0 : if (ret <= 0) ret--;
183 : : }
184 : : else
185 : 0 : free_string(s);
186 : : }
187 : 0 : return ret;
188 : : }
189 : :
190 : 0 : static int general_allocate_boolean(UI *ui,
191 : : const char *prompt, const char *action_desc,
192 : : const char *ok_chars, const char *cancel_chars,
193 : : int prompt_freeable, enum UI_string_types type, int input_flags,
194 : : char *result_buf)
195 : : {
196 : 0 : int ret = -1;
197 : : UI_STRING *s;
198 : : const char *p;
199 : :
200 [ # # ]: 0 : if (ok_chars == NULL)
201 : : {
202 : 0 : UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER);
203 : : }
204 [ # # ]: 0 : else if (cancel_chars == NULL)
205 : : {
206 : 0 : UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER);
207 : : }
208 : : else
209 : : {
210 [ # # ]: 0 : for(p = ok_chars; *p; p++)
211 : : {
212 [ # # ]: 0 : if (strchr(cancel_chars, *p))
213 : : {
214 : 0 : UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
215 : : UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
216 : : }
217 : : }
218 : :
219 : 0 : s = general_allocate_prompt(ui, prompt, prompt_freeable,
220 : : type, input_flags, result_buf);
221 : :
222 [ # # ]: 0 : if (s)
223 : : {
224 [ # # ]: 0 : if (allocate_string_stack(ui) >= 0)
225 : : {
226 : 0 : s->_.boolean_data.action_desc = action_desc;
227 : 0 : s->_.boolean_data.ok_chars = ok_chars;
228 : 0 : s->_.boolean_data.cancel_chars = cancel_chars;
229 : 0 : ret=sk_UI_STRING_push(ui->strings, s);
230 : : /* sk_push() returns 0 on error.
231 : : Let's addapt that */
232 [ # # ]: 0 : if (ret <= 0) ret--;
233 : : }
234 : : else
235 : 0 : free_string(s);
236 : : }
237 : : }
238 : 0 : return ret;
239 : : }
240 : :
241 : : /* Returns the index to the place in the stack or -1 for error. Uses a
242 : : direct reference to the prompt. */
243 : 0 : int UI_add_input_string(UI *ui, const char *prompt, int flags,
244 : : char *result_buf, int minsize, int maxsize)
245 : : {
246 : 0 : return general_allocate_string(ui, prompt, 0,
247 : : UIT_PROMPT, flags, result_buf, minsize, maxsize, NULL);
248 : : }
249 : :
250 : : /* Same as UI_add_input_string(), excepts it takes a copy of the prompt */
251 : 0 : int UI_dup_input_string(UI *ui, const char *prompt, int flags,
252 : : char *result_buf, int minsize, int maxsize)
253 : : {
254 : 0 : char *prompt_copy=NULL;
255 : :
256 [ # # ]: 0 : if (prompt)
257 : : {
258 : 0 : prompt_copy=BUF_strdup(prompt);
259 [ # # ]: 0 : if (prompt_copy == NULL)
260 : : {
261 : 0 : UIerr(UI_F_UI_DUP_INPUT_STRING,ERR_R_MALLOC_FAILURE);
262 : 0 : return 0;
263 : : }
264 : : }
265 : :
266 : 0 : return general_allocate_string(ui, prompt_copy, 1,
267 : : UIT_PROMPT, flags, result_buf, minsize, maxsize, NULL);
268 : : }
269 : :
270 : 0 : int UI_add_verify_string(UI *ui, const char *prompt, int flags,
271 : : char *result_buf, int minsize, int maxsize, const char *test_buf)
272 : : {
273 : 0 : return general_allocate_string(ui, prompt, 0,
274 : : UIT_VERIFY, flags, result_buf, minsize, maxsize, test_buf);
275 : : }
276 : :
277 : 0 : int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
278 : : char *result_buf, int minsize, int maxsize, const char *test_buf)
279 : : {
280 : 0 : char *prompt_copy=NULL;
281 : :
282 [ # # ]: 0 : if (prompt)
283 : : {
284 : 0 : prompt_copy=BUF_strdup(prompt);
285 [ # # ]: 0 : if (prompt_copy == NULL)
286 : : {
287 : 0 : UIerr(UI_F_UI_DUP_VERIFY_STRING,ERR_R_MALLOC_FAILURE);
288 : 0 : return -1;
289 : : }
290 : : }
291 : :
292 : 0 : return general_allocate_string(ui, prompt_copy, 1,
293 : : UIT_VERIFY, flags, result_buf, minsize, maxsize, test_buf);
294 : : }
295 : :
296 : 0 : int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
297 : : const char *ok_chars, const char *cancel_chars,
298 : : int flags, char *result_buf)
299 : : {
300 : 0 : return general_allocate_boolean(ui, prompt, action_desc,
301 : : ok_chars, cancel_chars, 0, UIT_BOOLEAN, flags, result_buf);
302 : : }
303 : :
304 : 0 : int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
305 : : const char *ok_chars, const char *cancel_chars,
306 : : int flags, char *result_buf)
307 : : {
308 : 0 : char *prompt_copy = NULL;
309 : 0 : char *action_desc_copy = NULL;
310 : 0 : char *ok_chars_copy = NULL;
311 : 0 : char *cancel_chars_copy = NULL;
312 : :
313 [ # # ]: 0 : if (prompt)
314 : : {
315 : 0 : prompt_copy=BUF_strdup(prompt);
316 [ # # ]: 0 : if (prompt_copy == NULL)
317 : : {
318 : 0 : UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
319 : 0 : goto err;
320 : : }
321 : : }
322 : :
323 [ # # ]: 0 : if (action_desc)
324 : : {
325 : 0 : action_desc_copy=BUF_strdup(action_desc);
326 [ # # ]: 0 : if (action_desc_copy == NULL)
327 : : {
328 : 0 : UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
329 : 0 : goto err;
330 : : }
331 : : }
332 : :
333 [ # # ]: 0 : if (ok_chars)
334 : : {
335 : 0 : ok_chars_copy=BUF_strdup(ok_chars);
336 [ # # ]: 0 : if (ok_chars_copy == NULL)
337 : : {
338 : 0 : UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
339 : 0 : goto err;
340 : : }
341 : : }
342 : :
343 [ # # ]: 0 : if (cancel_chars)
344 : : {
345 : 0 : cancel_chars_copy=BUF_strdup(cancel_chars);
346 [ # # ]: 0 : if (cancel_chars_copy == NULL)
347 : : {
348 : 0 : UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE);
349 : 0 : goto err;
350 : : }
351 : : }
352 : :
353 : 0 : return general_allocate_boolean(ui, prompt_copy, action_desc_copy,
354 : : ok_chars_copy, cancel_chars_copy, 1, UIT_BOOLEAN, flags,
355 : : result_buf);
356 : : err:
357 [ # # ]: 0 : if (prompt_copy) OPENSSL_free(prompt_copy);
358 [ # # ]: 0 : if (action_desc_copy) OPENSSL_free(action_desc_copy);
359 [ # # ]: 0 : if (ok_chars_copy) OPENSSL_free(ok_chars_copy);
360 [ # # ]: 0 : if (cancel_chars_copy) OPENSSL_free(cancel_chars_copy);
361 : : return -1;
362 : : }
363 : :
364 : 0 : int UI_add_info_string(UI *ui, const char *text)
365 : : {
366 : 0 : return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
367 : : NULL);
368 : : }
369 : :
370 : 0 : int UI_dup_info_string(UI *ui, const char *text)
371 : : {
372 : 0 : char *text_copy=NULL;
373 : :
374 [ # # ]: 0 : if (text)
375 : : {
376 : 0 : text_copy=BUF_strdup(text);
377 [ # # ]: 0 : if (text_copy == NULL)
378 : : {
379 : 0 : UIerr(UI_F_UI_DUP_INFO_STRING,ERR_R_MALLOC_FAILURE);
380 : 0 : return -1;
381 : : }
382 : : }
383 : :
384 : 0 : return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
385 : : 0, 0, NULL);
386 : : }
387 : :
388 : 0 : int UI_add_error_string(UI *ui, const char *text)
389 : : {
390 : 0 : return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
391 : : NULL);
392 : : }
393 : :
394 : 0 : int UI_dup_error_string(UI *ui, const char *text)
395 : : {
396 : 0 : char *text_copy=NULL;
397 : :
398 [ # # ]: 0 : if (text)
399 : : {
400 : 0 : text_copy=BUF_strdup(text);
401 [ # # ]: 0 : if (text_copy == NULL)
402 : : {
403 : 0 : UIerr(UI_F_UI_DUP_ERROR_STRING,ERR_R_MALLOC_FAILURE);
404 : 0 : return -1;
405 : : }
406 : : }
407 : 0 : return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL,
408 : : 0, 0, NULL);
409 : : }
410 : :
411 : 0 : char *UI_construct_prompt(UI *ui, const char *object_desc,
412 : : const char *object_name)
413 : : {
414 : 0 : char *prompt = NULL;
415 : :
416 [ # # ]: 0 : if (ui->meth->ui_construct_prompt)
417 : 0 : prompt = ui->meth->ui_construct_prompt(ui,
418 : : object_desc, object_name);
419 : : else
420 : : {
421 : 0 : char prompt1[] = "Enter ";
422 : 0 : char prompt2[] = " for ";
423 : 0 : char prompt3[] = ":";
424 : 0 : int len = 0;
425 : :
426 [ # # ]: 0 : if (object_desc == NULL)
427 : 0 : return NULL;
428 : 0 : len = sizeof(prompt1) - 1 + strlen(object_desc);
429 [ # # ]: 0 : if (object_name)
430 : 0 : len += sizeof(prompt2) - 1 + strlen(object_name);
431 : 0 : len += sizeof(prompt3) - 1;
432 : :
433 : 0 : prompt = (char *)OPENSSL_malloc(len + 1);
434 : 0 : BUF_strlcpy(prompt, prompt1, len + 1);
435 : 0 : BUF_strlcat(prompt, object_desc, len + 1);
436 [ # # ]: 0 : if (object_name)
437 : : {
438 : 0 : BUF_strlcat(prompt, prompt2, len + 1);
439 : 0 : BUF_strlcat(prompt, object_name, len + 1);
440 : : }
441 : 0 : BUF_strlcat(prompt, prompt3, len + 1);
442 : : }
443 : 0 : return prompt;
444 : : }
445 : :
446 : 0 : void *UI_add_user_data(UI *ui, void *user_data)
447 : : {
448 : 0 : void *old_data = ui->user_data;
449 : 0 : ui->user_data = user_data;
450 : 0 : return old_data;
451 : : }
452 : :
453 : 0 : void *UI_get0_user_data(UI *ui)
454 : : {
455 : 0 : return ui->user_data;
456 : : }
457 : :
458 : 0 : const char *UI_get0_result(UI *ui, int i)
459 : : {
460 [ # # ]: 0 : if (i < 0)
461 : : {
462 : 0 : UIerr(UI_F_UI_GET0_RESULT,UI_R_INDEX_TOO_SMALL);
463 : 0 : return NULL;
464 : : }
465 [ # # ]: 0 : if (i >= sk_UI_STRING_num(ui->strings))
466 : : {
467 : 0 : UIerr(UI_F_UI_GET0_RESULT,UI_R_INDEX_TOO_LARGE);
468 : 0 : return NULL;
469 : : }
470 : 0 : return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
471 : : }
472 : :
473 : 0 : static int print_error(const char *str, size_t len, UI *ui)
474 : : {
475 : : UI_STRING uis;
476 : :
477 : : memset(&uis, 0, sizeof(uis));
478 : 0 : uis.type = UIT_ERROR;
479 : 0 : uis.out_string = str;
480 : :
481 [ # # ]: 0 : if (ui->meth->ui_write_string
482 [ # # ]: 0 : && !ui->meth->ui_write_string(ui, &uis))
483 : : return -1;
484 : : return 0;
485 : : }
486 : :
487 : 0 : int UI_process(UI *ui)
488 : : {
489 : 0 : int i, ok=0;
490 : :
491 [ # # ][ # # ]: 0 : if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
492 : : return -1;
493 : :
494 [ # # ]: 0 : if (ui->flags & UI_FLAG_PRINT_ERRORS)
495 : 0 : ERR_print_errors_cb(
496 : : (int (*)(const char *, size_t, void *))print_error,
497 : : (void *)ui);
498 : :
499 [ # # ]: 0 : for(i=0; i<sk_UI_STRING_num(ui->strings); i++)
500 : : {
501 [ # # ]: 0 : if (ui->meth->ui_write_string
502 [ # # ]: 0 : && !ui->meth->ui_write_string(ui,
503 : 0 : sk_UI_STRING_value(ui->strings, i)))
504 : : {
505 : : ok=-1;
506 : : goto err;
507 : : }
508 : : }
509 : :
510 [ # # ]: 0 : if (ui->meth->ui_flush)
511 [ # # # ]: 0 : switch(ui->meth->ui_flush(ui))
512 : : {
513 : : case -1: /* Interrupt/Cancel/something... */
514 : : ok = -2;
515 : : goto err;
516 : : case 0: /* Errors */
517 : 0 : ok = -1;
518 : 0 : goto err;
519 : : default: /* Success */
520 : : ok = 0;
521 : : break;
522 : : }
523 : :
524 [ # # ]: 0 : for(i=0; i<sk_UI_STRING_num(ui->strings); i++)
525 : : {
526 [ # # ]: 0 : if (ui->meth->ui_read_string)
527 : : {
528 [ # # # ]: 0 : switch(ui->meth->ui_read_string(ui,
529 : 0 : sk_UI_STRING_value(ui->strings, i)))
530 : : {
531 : : case -1: /* Interrupt/Cancel/something... */
532 : : ok = -2;
533 : : goto err;
534 : : case 0: /* Errors */
535 : 0 : ok = -1;
536 : 0 : goto err;
537 : : default: /* Success */
538 : : ok = 0;
539 : : break;
540 : : }
541 : : }
542 : : }
543 : : err:
544 [ # # ][ # # ]: 0 : if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
545 : : return -1;
546 : 0 : return ok;
547 : : }
548 : :
549 : 0 : int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)(void))
550 : : {
551 [ # # ]: 0 : if (ui == NULL)
552 : : {
553 : 0 : UIerr(UI_F_UI_CTRL,ERR_R_PASSED_NULL_PARAMETER);
554 : 0 : return -1;
555 : : }
556 [ # # # ]: 0 : switch(cmd)
557 : : {
558 : : case UI_CTRL_PRINT_ERRORS:
559 : : {
560 : 0 : int save_flag = !!(ui->flags & UI_FLAG_PRINT_ERRORS);
561 [ # # ]: 0 : if (i)
562 : 0 : ui->flags |= UI_FLAG_PRINT_ERRORS;
563 : : else
564 : 0 : ui->flags &= ~UI_FLAG_PRINT_ERRORS;
565 : 0 : return save_flag;
566 : : }
567 : : case UI_CTRL_IS_REDOABLE:
568 : 0 : return !!(ui->flags & UI_FLAG_REDOABLE);
569 : : default:
570 : : break;
571 : : }
572 : 0 : UIerr(UI_F_UI_CTRL,UI_R_UNKNOWN_CONTROL_COMMAND);
573 : 0 : return -1;
574 : : }
575 : :
576 : 0 : int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
577 : : CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
578 : : {
579 : 0 : return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp,
580 : : new_func, dup_func, free_func);
581 : : }
582 : :
583 : 0 : int UI_set_ex_data(UI *r, int idx, void *arg)
584 : : {
585 : 0 : return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
586 : : }
587 : :
588 : 0 : void *UI_get_ex_data(UI *r, int idx)
589 : : {
590 : 0 : return(CRYPTO_get_ex_data(&r->ex_data,idx));
591 : : }
592 : :
593 : 0 : void UI_set_default_method(const UI_METHOD *meth)
594 : : {
595 : 0 : default_UI_meth=meth;
596 : 0 : }
597 : :
598 : 0 : const UI_METHOD *UI_get_default_method(void)
599 : : {
600 [ # # ]: 0 : if (default_UI_meth == NULL)
601 : : {
602 : 0 : default_UI_meth=UI_OpenSSL();
603 : : }
604 : 0 : return default_UI_meth;
605 : : }
606 : :
607 : 0 : const UI_METHOD *UI_get_method(UI *ui)
608 : : {
609 : 0 : return ui->meth;
610 : : }
611 : :
612 : 0 : const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth)
613 : : {
614 : 0 : ui->meth=meth;
615 : 0 : return ui->meth;
616 : : }
617 : :
618 : :
619 : 725 : UI_METHOD *UI_create_method(char *name)
620 : : {
621 : 725 : UI_METHOD *ui_method = (UI_METHOD *)OPENSSL_malloc(sizeof(UI_METHOD));
622 : :
623 [ + - ]: 725 : if (ui_method)
624 : : {
625 : : memset(ui_method, 0, sizeof(*ui_method));
626 : 725 : ui_method->name = BUF_strdup(name);
627 : : }
628 : 725 : return ui_method;
629 : : }
630 : :
631 : : /* BIG FSCKING WARNING!!!! If you use this on a statically allocated method
632 : : (that is, it hasn't been allocated using UI_create_method(), you deserve
633 : : anything Murphy can throw at you and more! You have been warned. */
634 : 725 : void UI_destroy_method(UI_METHOD *ui_method)
635 : : {
636 : 725 : OPENSSL_free(ui_method->name);
637 : 725 : ui_method->name = NULL;
638 : 725 : OPENSSL_free(ui_method);
639 : 725 : }
640 : :
641 : 725 : int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui))
642 : : {
643 [ + - ]: 725 : if (method)
644 : : {
645 : 725 : method->ui_open_session = opener;
646 : 725 : return 0;
647 : : }
648 : : else
649 : : return -1;
650 : : }
651 : :
652 : 725 : int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis))
653 : : {
654 [ + - ]: 725 : if (method)
655 : : {
656 : 725 : method->ui_write_string = writer;
657 : 725 : return 0;
658 : : }
659 : : else
660 : : return -1;
661 : : }
662 : :
663 : 0 : int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui))
664 : : {
665 [ # # ]: 0 : if (method)
666 : : {
667 : 0 : method->ui_flush = flusher;
668 : 0 : return 0;
669 : : }
670 : : else
671 : : return -1;
672 : : }
673 : :
674 : 725 : int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis))
675 : : {
676 [ + - ]: 725 : if (method)
677 : : {
678 : 725 : method->ui_read_string = reader;
679 : 725 : return 0;
680 : : }
681 : : else
682 : : return -1;
683 : : }
684 : :
685 : 725 : int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui))
686 : : {
687 [ + - ]: 725 : if (method)
688 : : {
689 : 725 : method->ui_close_session = closer;
690 : 725 : return 0;
691 : : }
692 : : else
693 : : return -1;
694 : : }
695 : :
696 : 0 : int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name))
697 : : {
698 [ # # ]: 0 : if (method)
699 : : {
700 : 0 : method->ui_construct_prompt = prompt_constructor;
701 : 0 : return 0;
702 : : }
703 : : else
704 : : return -1;
705 : : }
706 : :
707 : 0 : int (*UI_method_get_opener(UI_METHOD *method))(UI*)
708 : : {
709 [ # # ]: 0 : if (method)
710 : 0 : return method->ui_open_session;
711 : : else
712 : : return NULL;
713 : : }
714 : :
715 : 0 : int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*)
716 : : {
717 [ # # ]: 0 : if (method)
718 : 0 : return method->ui_write_string;
719 : : else
720 : : return NULL;
721 : : }
722 : :
723 : 0 : int (*UI_method_get_flusher(UI_METHOD *method))(UI*)
724 : : {
725 [ # # ]: 0 : if (method)
726 : 0 : return method->ui_flush;
727 : : else
728 : : return NULL;
729 : : }
730 : :
731 : 0 : int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*)
732 : : {
733 [ # # ]: 0 : if (method)
734 : 0 : return method->ui_read_string;
735 : : else
736 : : return NULL;
737 : : }
738 : :
739 : 0 : int (*UI_method_get_closer(UI_METHOD *method))(UI*)
740 : : {
741 [ # # ]: 0 : if (method)
742 : 0 : return method->ui_close_session;
743 : : else
744 : : return NULL;
745 : : }
746 : :
747 : 0 : char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*)
748 : : {
749 [ # # ]: 0 : if (method)
750 : 0 : return method->ui_construct_prompt;
751 : : else
752 : : return NULL;
753 : : }
754 : :
755 : 0 : enum UI_string_types UI_get_string_type(UI_STRING *uis)
756 : : {
757 [ # # ]: 0 : if (!uis)
758 : : return UIT_NONE;
759 : 0 : return uis->type;
760 : : }
761 : :
762 : 0 : int UI_get_input_flags(UI_STRING *uis)
763 : : {
764 [ # # ]: 0 : if (!uis)
765 : : return 0;
766 : 0 : return uis->input_flags;
767 : : }
768 : :
769 : 0 : const char *UI_get0_output_string(UI_STRING *uis)
770 : : {
771 [ # # ]: 0 : if (!uis)
772 : : return NULL;
773 : 0 : return uis->out_string;
774 : : }
775 : :
776 : 0 : const char *UI_get0_action_string(UI_STRING *uis)
777 : : {
778 [ # # ]: 0 : if (!uis)
779 : : return NULL;
780 [ # # ]: 0 : switch(uis->type)
781 : : {
782 : : case UIT_PROMPT:
783 : : case UIT_BOOLEAN:
784 : 0 : return uis->_.boolean_data.action_desc;
785 : : default:
786 : : return NULL;
787 : : }
788 : : }
789 : :
790 : 0 : const char *UI_get0_result_string(UI_STRING *uis)
791 : : {
792 [ # # ]: 0 : if (!uis)
793 : : return NULL;
794 [ # # ]: 0 : switch(uis->type)
795 : : {
796 : : case UIT_PROMPT:
797 : : case UIT_VERIFY:
798 : 0 : return uis->result_buf;
799 : : default:
800 : : return NULL;
801 : : }
802 : : }
803 : :
804 : 0 : const char *UI_get0_test_string(UI_STRING *uis)
805 : : {
806 [ # # ]: 0 : if (!uis)
807 : : return NULL;
808 [ # # ]: 0 : switch(uis->type)
809 : : {
810 : : case UIT_VERIFY:
811 : 0 : return uis->_.string_data.test_buf;
812 : : default:
813 : : return NULL;
814 : : }
815 : : }
816 : :
817 : 0 : int UI_get_result_minsize(UI_STRING *uis)
818 : : {
819 [ # # ]: 0 : if (!uis)
820 : : return -1;
821 [ # # ]: 0 : switch(uis->type)
822 : : {
823 : : case UIT_PROMPT:
824 : : case UIT_VERIFY:
825 : 0 : return uis->_.string_data.result_minsize;
826 : : default:
827 : : return -1;
828 : : }
829 : : }
830 : :
831 : 0 : int UI_get_result_maxsize(UI_STRING *uis)
832 : : {
833 [ # # ]: 0 : if (!uis)
834 : : return -1;
835 [ # # ]: 0 : switch(uis->type)
836 : : {
837 : : case UIT_PROMPT:
838 : : case UIT_VERIFY:
839 : 0 : return uis->_.string_data.result_maxsize;
840 : : default:
841 : : return -1;
842 : : }
843 : : }
844 : :
845 : 0 : int UI_set_result(UI *ui, UI_STRING *uis, const char *result)
846 : : {
847 : 0 : int l = strlen(result);
848 : :
849 : 0 : ui->flags &= ~UI_FLAG_REDOABLE;
850 : :
851 [ # # ]: 0 : if (!uis)
852 : : return -1;
853 [ # # # ]: 0 : switch (uis->type)
854 : : {
855 : : case UIT_PROMPT:
856 : : case UIT_VERIFY:
857 : : {
858 : : char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize)+1];
859 : : char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize)+1];
860 : :
861 : 0 : BIO_snprintf(number1, sizeof(number1), "%d",
862 : : uis->_.string_data.result_minsize);
863 : 0 : BIO_snprintf(number2, sizeof(number2), "%d",
864 : : uis->_.string_data.result_maxsize);
865 : :
866 [ # # ]: 0 : if (l < uis->_.string_data.result_minsize)
867 : : {
868 : 0 : ui->flags |= UI_FLAG_REDOABLE;
869 : 0 : UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_SMALL);
870 : 0 : ERR_add_error_data(5,"You must type in ",
871 : : number1," to ",number2," characters");
872 : 0 : return -1;
873 : : }
874 [ # # ]: 0 : if (l > uis->_.string_data.result_maxsize)
875 : : {
876 : 0 : ui->flags |= UI_FLAG_REDOABLE;
877 : 0 : UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_LARGE);
878 : 0 : ERR_add_error_data(5,"You must type in ",
879 : : number1," to ",number2," characters");
880 : 0 : return -1;
881 : : }
882 : : }
883 : :
884 [ # # ]: 0 : if (!uis->result_buf)
885 : : {
886 : 0 : UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER);
887 : 0 : return -1;
888 : : }
889 : :
890 : 0 : BUF_strlcpy(uis->result_buf, result,
891 : 0 : uis->_.string_data.result_maxsize + 1);
892 : 0 : break;
893 : : case UIT_BOOLEAN:
894 : : {
895 : : const char *p;
896 : :
897 [ # # ]: 0 : if (!uis->result_buf)
898 : : {
899 : 0 : UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER);
900 : 0 : return -1;
901 : : }
902 : :
903 : 0 : uis->result_buf[0] = '\0';
904 [ # # ]: 0 : for(p = result; *p; p++)
905 : : {
906 [ # # ]: 0 : if (strchr(uis->_.boolean_data.ok_chars, *p))
907 : : {
908 : 0 : uis->result_buf[0] =
909 : 0 : uis->_.boolean_data.ok_chars[0];
910 : 0 : break;
911 : : }
912 [ # # ]: 0 : if (strchr(uis->_.boolean_data.cancel_chars, *p))
913 : : {
914 : 0 : uis->result_buf[0] =
915 : 0 : uis->_.boolean_data.cancel_chars[0];
916 : 0 : break;
917 : : }
918 : : }
919 : : }
920 : : default:
921 : : break;
922 : : }
923 : : return 0;
924 : : }
|