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