]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/ui/ui_lib.c
Add some error messages for malloc fails
[thirdparty/openssl.git] / crypto / ui / ui_lib.c
1 /*
2 * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <string.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/e_os2.h>
13 #include <openssl/buffer.h>
14 #include <openssl/ui.h>
15 #include <openssl/err.h>
16 #include "ui_locl.h"
17
18 static const UI_METHOD *default_UI_meth = NULL;
19
20 UI *UI_new(void)
21 {
22 return (UI_new_method(NULL));
23 }
24
25 UI *UI_new_method(const UI_METHOD *method)
26 {
27 UI *ret = OPENSSL_zalloc(sizeof(*ret));
28
29 if (ret == NULL) {
30 UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE);
31 return NULL;
32 }
33
34 ret->lock = CRYPTO_THREAD_lock_new();
35 if (ret->lock == NULL) {
36 UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE);
37 OPENSSL_free(ret);
38 return NULL;
39 }
40
41 if (method == NULL)
42 ret->meth = UI_get_default_method();
43 else
44 ret->meth = method;
45
46 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data)) {
47 OPENSSL_free(ret);
48 return NULL;
49 }
50 return ret;
51 }
52
53 static void free_string(UI_STRING *uis)
54 {
55 if (uis->flags & OUT_STRING_FREEABLE) {
56 OPENSSL_free((char *)uis->out_string);
57 switch (uis->type) {
58 case UIT_BOOLEAN:
59 OPENSSL_free((char *)uis->_.boolean_data.action_desc);
60 OPENSSL_free((char *)uis->_.boolean_data.ok_chars);
61 OPENSSL_free((char *)uis->_.boolean_data.cancel_chars);
62 break;
63 default:
64 break;
65 }
66 }
67 OPENSSL_free(uis);
68 }
69
70 void UI_free(UI *ui)
71 {
72 if (ui == NULL)
73 return;
74 sk_UI_STRING_pop_free(ui->strings, free_string);
75 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data);
76 CRYPTO_THREAD_lock_free(ui->lock);
77 OPENSSL_free(ui);
78 }
79
80 static int allocate_string_stack(UI *ui)
81 {
82 if (ui->strings == NULL) {
83 ui->strings = sk_UI_STRING_new_null();
84 if (ui->strings == NULL) {
85 return -1;
86 }
87 }
88 return 0;
89 }
90
91 static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt,
92 int prompt_freeable,
93 enum UI_string_types type,
94 int input_flags, char *result_buf)
95 {
96 UI_STRING *ret = NULL;
97
98 if (prompt == NULL) {
99 UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, ERR_R_PASSED_NULL_PARAMETER);
100 } else if ((type == UIT_PROMPT || type == UIT_VERIFY
101 || type == UIT_BOOLEAN) && result_buf == NULL) {
102 UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, UI_R_NO_RESULT_BUFFER);
103 } else if ((ret = OPENSSL_malloc(sizeof(*ret))) != NULL) {
104 ret->out_string = prompt;
105 ret->flags = prompt_freeable ? OUT_STRING_FREEABLE : 0;
106 ret->input_flags = input_flags;
107 ret->type = type;
108 ret->result_buf = result_buf;
109 }
110 return ret;
111 }
112
113 static int general_allocate_string(UI *ui, const char *prompt,
114 int prompt_freeable,
115 enum UI_string_types type, int input_flags,
116 char *result_buf, int minsize, int maxsize,
117 const char *test_buf)
118 {
119 int ret = -1;
120 UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
121 type, input_flags, result_buf);
122
123 if (s) {
124 if (allocate_string_stack(ui) >= 0) {
125 s->_.string_data.result_minsize = minsize;
126 s->_.string_data.result_maxsize = maxsize;
127 s->_.string_data.test_buf = test_buf;
128 ret = sk_UI_STRING_push(ui->strings, s);
129 /* sk_push() returns 0 on error. Let's adapt that */
130 if (ret <= 0)
131 ret--;
132 } else
133 free_string(s);
134 }
135 return ret;
136 }
137
138 static int general_allocate_boolean(UI *ui,
139 const char *prompt,
140 const char *action_desc,
141 const char *ok_chars,
142 const char *cancel_chars,
143 int prompt_freeable,
144 enum UI_string_types type,
145 int input_flags, char *result_buf)
146 {
147 int ret = -1;
148 UI_STRING *s;
149 const char *p;
150
151 if (ok_chars == NULL) {
152 UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER);
153 } else if (cancel_chars == NULL) {
154 UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER);
155 } else {
156 for (p = ok_chars; *p; p++) {
157 if (strchr(cancel_chars, *p)) {
158 UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
159 UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
160 }
161 }
162
163 s = general_allocate_prompt(ui, prompt, prompt_freeable,
164 type, input_flags, result_buf);
165
166 if (s) {
167 if (allocate_string_stack(ui) >= 0) {
168 s->_.boolean_data.action_desc = action_desc;
169 s->_.boolean_data.ok_chars = ok_chars;
170 s->_.boolean_data.cancel_chars = cancel_chars;
171 ret = sk_UI_STRING_push(ui->strings, s);
172 /*
173 * sk_push() returns 0 on error. Let's adapt that
174 */
175 if (ret <= 0)
176 ret--;
177 } else
178 free_string(s);
179 }
180 }
181 return ret;
182 }
183
184 /*
185 * Returns the index to the place in the stack or -1 for error. Uses a
186 * direct reference to the prompt.
187 */
188 int UI_add_input_string(UI *ui, const char *prompt, int flags,
189 char *result_buf, int minsize, int maxsize)
190 {
191 return general_allocate_string(ui, prompt, 0,
192 UIT_PROMPT, flags, result_buf, minsize,
193 maxsize, NULL);
194 }
195
196 /* Same as UI_add_input_string(), excepts it takes a copy of the prompt */
197 int UI_dup_input_string(UI *ui, const char *prompt, int flags,
198 char *result_buf, int minsize, int maxsize)
199 {
200 char *prompt_copy = NULL;
201
202 if (prompt) {
203 prompt_copy = OPENSSL_strdup(prompt);
204 if (prompt_copy == NULL) {
205 UIerr(UI_F_UI_DUP_INPUT_STRING, ERR_R_MALLOC_FAILURE);
206 return 0;
207 }
208 }
209
210 return general_allocate_string(ui, prompt_copy, 1,
211 UIT_PROMPT, flags, result_buf, minsize,
212 maxsize, NULL);
213 }
214
215 int UI_add_verify_string(UI *ui, const char *prompt, int flags,
216 char *result_buf, int minsize, int maxsize,
217 const char *test_buf)
218 {
219 return general_allocate_string(ui, prompt, 0,
220 UIT_VERIFY, flags, result_buf, minsize,
221 maxsize, test_buf);
222 }
223
224 int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
225 char *result_buf, int minsize, int maxsize,
226 const char *test_buf)
227 {
228 char *prompt_copy = NULL;
229
230 if (prompt) {
231 prompt_copy = OPENSSL_strdup(prompt);
232 if (prompt_copy == NULL) {
233 UIerr(UI_F_UI_DUP_VERIFY_STRING, ERR_R_MALLOC_FAILURE);
234 return -1;
235 }
236 }
237
238 return general_allocate_string(ui, prompt_copy, 1,
239 UIT_VERIFY, flags, result_buf, minsize,
240 maxsize, test_buf);
241 }
242
243 int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
244 const char *ok_chars, const char *cancel_chars,
245 int flags, char *result_buf)
246 {
247 return general_allocate_boolean(ui, prompt, action_desc,
248 ok_chars, cancel_chars, 0, UIT_BOOLEAN,
249 flags, result_buf);
250 }
251
252 int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
253 const char *ok_chars, const char *cancel_chars,
254 int flags, char *result_buf)
255 {
256 char *prompt_copy = NULL;
257 char *action_desc_copy = NULL;
258 char *ok_chars_copy = NULL;
259 char *cancel_chars_copy = NULL;
260
261 if (prompt) {
262 prompt_copy = OPENSSL_strdup(prompt);
263 if (prompt_copy == NULL) {
264 UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
265 goto err;
266 }
267 }
268
269 if (action_desc) {
270 action_desc_copy = OPENSSL_strdup(action_desc);
271 if (action_desc_copy == NULL) {
272 UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
273 goto err;
274 }
275 }
276
277 if (ok_chars) {
278 ok_chars_copy = OPENSSL_strdup(ok_chars);
279 if (ok_chars_copy == NULL) {
280 UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
281 goto err;
282 }
283 }
284
285 if (cancel_chars) {
286 cancel_chars_copy = OPENSSL_strdup(cancel_chars);
287 if (cancel_chars_copy == NULL) {
288 UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
289 goto err;
290 }
291 }
292
293 return general_allocate_boolean(ui, prompt_copy, action_desc_copy,
294 ok_chars_copy, cancel_chars_copy, 1,
295 UIT_BOOLEAN, flags, result_buf);
296 err:
297 OPENSSL_free(prompt_copy);
298 OPENSSL_free(action_desc_copy);
299 OPENSSL_free(ok_chars_copy);
300 OPENSSL_free(cancel_chars_copy);
301 return -1;
302 }
303
304 int UI_add_info_string(UI *ui, const char *text)
305 {
306 return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
307 NULL);
308 }
309
310 int UI_dup_info_string(UI *ui, const char *text)
311 {
312 char *text_copy = NULL;
313
314 if (text) {
315 text_copy = OPENSSL_strdup(text);
316 if (text_copy == NULL) {
317 UIerr(UI_F_UI_DUP_INFO_STRING, ERR_R_MALLOC_FAILURE);
318 return -1;
319 }
320 }
321
322 return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
323 0, 0, NULL);
324 }
325
326 int UI_add_error_string(UI *ui, const char *text)
327 {
328 return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
329 NULL);
330 }
331
332 int UI_dup_error_string(UI *ui, const char *text)
333 {
334 char *text_copy = NULL;
335
336 if (text) {
337 text_copy = OPENSSL_strdup(text);
338 if (text_copy == NULL) {
339 UIerr(UI_F_UI_DUP_ERROR_STRING, ERR_R_MALLOC_FAILURE);
340 return -1;
341 }
342 }
343 return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL,
344 0, 0, NULL);
345 }
346
347 char *UI_construct_prompt(UI *ui, const char *object_desc,
348 const char *object_name)
349 {
350 char *prompt = NULL;
351
352 if (ui->meth->ui_construct_prompt)
353 prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name);
354 else {
355 char prompt1[] = "Enter ";
356 char prompt2[] = " for ";
357 char prompt3[] = ":";
358 int len = 0;
359
360 if (object_desc == NULL)
361 return NULL;
362 len = sizeof(prompt1) - 1 + strlen(object_desc);
363 if (object_name)
364 len += sizeof(prompt2) - 1 + strlen(object_name);
365 len += sizeof(prompt3) - 1;
366
367 prompt = OPENSSL_malloc(len + 1);
368 if (prompt == NULL)
369 return NULL;
370 OPENSSL_strlcpy(prompt, prompt1, len + 1);
371 OPENSSL_strlcat(prompt, object_desc, len + 1);
372 if (object_name) {
373 OPENSSL_strlcat(prompt, prompt2, len + 1);
374 OPENSSL_strlcat(prompt, object_name, len + 1);
375 }
376 OPENSSL_strlcat(prompt, prompt3, len + 1);
377 }
378 return prompt;
379 }
380
381 void *UI_add_user_data(UI *ui, void *user_data)
382 {
383 void *old_data = ui->user_data;
384 ui->user_data = user_data;
385 return old_data;
386 }
387
388 void *UI_get0_user_data(UI *ui)
389 {
390 return ui->user_data;
391 }
392
393 const char *UI_get0_result(UI *ui, int i)
394 {
395 if (i < 0) {
396 UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_SMALL);
397 return NULL;
398 }
399 if (i >= sk_UI_STRING_num(ui->strings)) {
400 UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_LARGE);
401 return NULL;
402 }
403 return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
404 }
405
406 static int print_error(const char *str, size_t len, UI *ui)
407 {
408 UI_STRING uis;
409
410 memset(&uis, 0, sizeof(uis));
411 uis.type = UIT_ERROR;
412 uis.out_string = str;
413
414 if (ui->meth->ui_write_string && !ui->meth->ui_write_string(ui, &uis))
415 return -1;
416 return 0;
417 }
418
419 int UI_process(UI *ui)
420 {
421 int i, ok = 0;
422
423 if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
424 return -1;
425
426 if (ui->flags & UI_FLAG_PRINT_ERRORS)
427 ERR_print_errors_cb((int (*)(const char *, size_t, void *))
428 print_error, (void *)ui);
429
430 for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
431 if (ui->meth->ui_write_string
432 && !ui->meth->ui_write_string(ui,
433 sk_UI_STRING_value(ui->strings, i)))
434 {
435 ok = -1;
436 goto err;
437 }
438 }
439
440 if (ui->meth->ui_flush)
441 switch (ui->meth->ui_flush(ui)) {
442 case -1: /* Interrupt/Cancel/something... */
443 ok = -2;
444 goto err;
445 case 0: /* Errors */
446 ok = -1;
447 goto err;
448 default: /* Success */
449 ok = 0;
450 break;
451 }
452
453 for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
454 if (ui->meth->ui_read_string) {
455 switch (ui->meth->ui_read_string(ui,
456 sk_UI_STRING_value(ui->strings,
457 i))) {
458 case -1: /* Interrupt/Cancel/something... */
459 ok = -2;
460 goto err;
461 case 0: /* Errors */
462 ok = -1;
463 goto err;
464 default: /* Success */
465 ok = 0;
466 break;
467 }
468 }
469 }
470 err:
471 if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
472 return -1;
473 return ok;
474 }
475
476 int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void))
477 {
478 if (ui == NULL) {
479 UIerr(UI_F_UI_CTRL, ERR_R_PASSED_NULL_PARAMETER);
480 return -1;
481 }
482 switch (cmd) {
483 case UI_CTRL_PRINT_ERRORS:
484 {
485 int save_flag = ! !(ui->flags & UI_FLAG_PRINT_ERRORS);
486 if (i)
487 ui->flags |= UI_FLAG_PRINT_ERRORS;
488 else
489 ui->flags &= ~UI_FLAG_PRINT_ERRORS;
490 return save_flag;
491 }
492 case UI_CTRL_IS_REDOABLE:
493 return ! !(ui->flags & UI_FLAG_REDOABLE);
494 default:
495 break;
496 }
497 UIerr(UI_F_UI_CTRL, UI_R_UNKNOWN_CONTROL_COMMAND);
498 return -1;
499 }
500
501 int UI_set_ex_data(UI *r, int idx, void *arg)
502 {
503 return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
504 }
505
506 void *UI_get_ex_data(UI *r, int idx)
507 {
508 return (CRYPTO_get_ex_data(&r->ex_data, idx));
509 }
510
511 void UI_set_default_method(const UI_METHOD *meth)
512 {
513 default_UI_meth = meth;
514 }
515
516 const UI_METHOD *UI_get_default_method(void)
517 {
518 if (default_UI_meth == NULL) {
519 default_UI_meth = UI_OpenSSL();
520 }
521 return default_UI_meth;
522 }
523
524 const UI_METHOD *UI_get_method(UI *ui)
525 {
526 return ui->meth;
527 }
528
529 const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth)
530 {
531 ui->meth = meth;
532 return ui->meth;
533 }
534
535 UI_METHOD *UI_create_method(char *name)
536 {
537 UI_METHOD *ui_method = OPENSSL_zalloc(sizeof(*ui_method));
538
539 if (ui_method != NULL) {
540 ui_method->name = OPENSSL_strdup(name);
541 if (ui_method->name == NULL) {
542 OPENSSL_free(ui_method);
543 UIerr(UI_F_UI_CREATE_METHOD, ERR_R_MALLOC_FAILURE);
544 return NULL;
545 }
546 }
547 return ui_method;
548 }
549
550 /*
551 * BIG FSCKING WARNING!!!! If you use this on a statically allocated method
552 * (that is, it hasn't been allocated using UI_create_method(), you deserve
553 * anything Murphy can throw at you and more! You have been warned.
554 */
555 void UI_destroy_method(UI_METHOD *ui_method)
556 {
557 OPENSSL_free(ui_method->name);
558 ui_method->name = NULL;
559 OPENSSL_free(ui_method);
560 }
561
562 int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui))
563 {
564 if (method) {
565 method->ui_open_session = opener;
566 return 0;
567 } else
568 return -1;
569 }
570
571 int UI_method_set_writer(UI_METHOD *method,
572 int (*writer) (UI *ui, UI_STRING *uis))
573 {
574 if (method) {
575 method->ui_write_string = writer;
576 return 0;
577 } else
578 return -1;
579 }
580
581 int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui))
582 {
583 if (method) {
584 method->ui_flush = flusher;
585 return 0;
586 } else
587 return -1;
588 }
589
590 int UI_method_set_reader(UI_METHOD *method,
591 int (*reader) (UI *ui, UI_STRING *uis))
592 {
593 if (method) {
594 method->ui_read_string = reader;
595 return 0;
596 } else
597 return -1;
598 }
599
600 int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui))
601 {
602 if (method) {
603 method->ui_close_session = closer;
604 return 0;
605 } else
606 return -1;
607 }
608
609 int UI_method_set_prompt_constructor(UI_METHOD *method,
610 char *(*prompt_constructor) (UI *ui,
611 const char
612 *object_desc,
613 const char
614 *object_name))
615 {
616 if (method) {
617 method->ui_construct_prompt = prompt_constructor;
618 return 0;
619 } else
620 return -1;
621 }
622
623 int (*UI_method_get_opener(UI_METHOD *method)) (UI *) {
624 if (method)
625 return method->ui_open_session;
626 else
627 return NULL;
628 }
629
630 int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *) {
631 if (method)
632 return method->ui_write_string;
633 else
634 return NULL;
635 }
636
637 int (*UI_method_get_flusher(UI_METHOD *method)) (UI *) {
638 if (method)
639 return method->ui_flush;
640 else
641 return NULL;
642 }
643
644 int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *) {
645 if (method)
646 return method->ui_read_string;
647 else
648 return NULL;
649 }
650
651 int (*UI_method_get_closer(UI_METHOD *method)) (UI *) {
652 if (method)
653 return method->ui_close_session;
654 else
655 return NULL;
656 }
657
658 char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
659 const char *,
660 const char *) {
661 if (method)
662 return method->ui_construct_prompt;
663 else
664 return NULL;
665 }
666
667 enum UI_string_types UI_get_string_type(UI_STRING *uis)
668 {
669 if (!uis)
670 return UIT_NONE;
671 return uis->type;
672 }
673
674 int UI_get_input_flags(UI_STRING *uis)
675 {
676 if (!uis)
677 return 0;
678 return uis->input_flags;
679 }
680
681 const char *UI_get0_output_string(UI_STRING *uis)
682 {
683 if (!uis)
684 return NULL;
685 return uis->out_string;
686 }
687
688 const char *UI_get0_action_string(UI_STRING *uis)
689 {
690 if (!uis)
691 return NULL;
692 switch (uis->type) {
693 case UIT_PROMPT:
694 case UIT_BOOLEAN:
695 return uis->_.boolean_data.action_desc;
696 default:
697 return NULL;
698 }
699 }
700
701 const char *UI_get0_result_string(UI_STRING *uis)
702 {
703 if (!uis)
704 return NULL;
705 switch (uis->type) {
706 case UIT_PROMPT:
707 case UIT_VERIFY:
708 return uis->result_buf;
709 default:
710 return NULL;
711 }
712 }
713
714 const char *UI_get0_test_string(UI_STRING *uis)
715 {
716 if (!uis)
717 return NULL;
718 switch (uis->type) {
719 case UIT_VERIFY:
720 return uis->_.string_data.test_buf;
721 default:
722 return NULL;
723 }
724 }
725
726 int UI_get_result_minsize(UI_STRING *uis)
727 {
728 if (!uis)
729 return -1;
730 switch (uis->type) {
731 case UIT_PROMPT:
732 case UIT_VERIFY:
733 return uis->_.string_data.result_minsize;
734 default:
735 return -1;
736 }
737 }
738
739 int UI_get_result_maxsize(UI_STRING *uis)
740 {
741 if (!uis)
742 return -1;
743 switch (uis->type) {
744 case UIT_PROMPT:
745 case UIT_VERIFY:
746 return uis->_.string_data.result_maxsize;
747 default:
748 return -1;
749 }
750 }
751
752 int UI_set_result(UI *ui, UI_STRING *uis, const char *result)
753 {
754 int l = strlen(result);
755
756 ui->flags &= ~UI_FLAG_REDOABLE;
757
758 if (!uis)
759 return -1;
760 switch (uis->type) {
761 case UIT_PROMPT:
762 case UIT_VERIFY:
763 {
764 char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize) + 1];
765 char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize) + 1];
766
767 BIO_snprintf(number1, sizeof(number1), "%d",
768 uis->_.string_data.result_minsize);
769 BIO_snprintf(number2, sizeof(number2), "%d",
770 uis->_.string_data.result_maxsize);
771
772 if (l < uis->_.string_data.result_minsize) {
773 ui->flags |= UI_FLAG_REDOABLE;
774 UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_SMALL);
775 ERR_add_error_data(5, "You must type in ",
776 number1, " to ", number2, " characters");
777 return -1;
778 }
779 if (l > uis->_.string_data.result_maxsize) {
780 ui->flags |= UI_FLAG_REDOABLE;
781 UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_LARGE);
782 ERR_add_error_data(5, "You must type in ",
783 number1, " to ", number2, " characters");
784 return -1;
785 }
786 }
787
788 if (!uis->result_buf) {
789 UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
790 return -1;
791 }
792
793 OPENSSL_strlcpy(uis->result_buf, result,
794 uis->_.string_data.result_maxsize + 1);
795 break;
796 case UIT_BOOLEAN:
797 {
798 const char *p;
799
800 if (!uis->result_buf) {
801 UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
802 return -1;
803 }
804
805 uis->result_buf[0] = '\0';
806 for (p = result; *p; p++) {
807 if (strchr(uis->_.boolean_data.ok_chars, *p)) {
808 uis->result_buf[0] = uis->_.boolean_data.ok_chars[0];
809 break;
810 }
811 if (strchr(uis->_.boolean_data.cancel_chars, *p)) {
812 uis->result_buf[0] = uis->_.boolean_data.cancel_chars[0];
813 break;
814 }
815 }
816 }
817 default:
818 break;
819 }
820 return 0;
821 }