]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/ui/ui_lib.c
Copyright consolidation 05/10
[thirdparty/openssl.git] / crypto / ui / ui_lib.c
CommitLineData
0f113f3e 1/*
aa6bb135 2 * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
a63d5eaa 3 *
aa6bb135
RS
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
a63d5eaa
RL
8 */
9
10#include <string.h>
b39fc560 11#include "internal/cryptlib.h"
eb929eef
RL
12#include <openssl/e_os2.h>
13#include <openssl/buffer.h>
a63d5eaa
RL
14#include <openssl/ui.h>
15#include <openssl/err.h>
16#include "ui_locl.h"
17
0f113f3e 18static const UI_METHOD *default_UI_meth = NULL;
a63d5eaa
RL
19
20UI *UI_new(void)
0f113f3e
MC
21{
22 return (UI_new_method(NULL));
23}
a63d5eaa
RL
24
25UI *UI_new_method(const UI_METHOD *method)
0f113f3e 26{
64b25758 27 UI *ret = OPENSSL_zalloc(sizeof(*ret));
0f113f3e 28
0f113f3e
MC
29 if (ret == NULL) {
30 UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE);
31 return NULL;
32 }
41cfbccc
AG
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
0f113f3e
MC
41 if (method == NULL)
42 ret->meth = UI_get_default_method();
43 else
44 ret->meth = method;
45
25a807bc
F
46 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data)) {
47 OPENSSL_free(ret);
48 return NULL;
49 }
0f113f3e
MC
50 return ret;
51}
a63d5eaa 52
d6f188be 53static void free_string(UI_STRING *uis)
0f113f3e
MC
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}
a63d5eaa
RL
69
70void UI_free(UI *ui)
0f113f3e
MC
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);
41cfbccc 76 CRYPTO_THREAD_lock_free(ui->lock);
0f113f3e
MC
77 OPENSSL_free(ui);
78}
a63d5eaa
RL
79
80static int allocate_string_stack(UI *ui)
0f113f3e
MC
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}
a63d5eaa 90
2d2ed9df 91static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt,
0f113f3e
MC
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);
90945fa3 103 } else if ((ret = OPENSSL_malloc(sizeof(*ret))) != NULL) {
0f113f3e
MC
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}
2d2ed9df 112
a63d5eaa 113static int general_allocate_string(UI *ui, const char *prompt,
0f113f3e
MC
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);
0d4fb843 129 /* sk_push() returns 0 on error. Let's adapt that */
0f113f3e
MC
130 if (ret <= 0)
131 ret--;
132 } else
133 free_string(s);
134 }
135 return ret;
136}
2d2ed9df
RL
137
138static int general_allocate_boolean(UI *ui,
0f113f3e
MC
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 /*
0d4fb843 173 * sk_push() returns 0 on error. Let's adapt that
0f113f3e
MC
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 */
9ad0f681 188int UI_add_input_string(UI *ui, const char *prompt, int flags,
0f113f3e
MC
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}
a63d5eaa
RL
195
196/* Same as UI_add_input_string(), excepts it takes a copy of the prompt */
9ad0f681 197int UI_dup_input_string(UI *ui, const char *prompt, int flags,
0f113f3e
MC
198 char *result_buf, int minsize, int maxsize)
199{
200 char *prompt_copy = NULL;
201
202 if (prompt) {
7644a9ae 203 prompt_copy = OPENSSL_strdup(prompt);
0f113f3e
MC
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}
a63d5eaa 214
9ad0f681 215int UI_add_verify_string(UI *ui, const char *prompt, int flags,
0f113f3e
MC
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}
a63d5eaa 223
9ad0f681 224int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
0f113f3e
MC
225 char *result_buf, int minsize, int maxsize,
226 const char *test_buf)
227{
228 char *prompt_copy = NULL;
229
230 if (prompt) {
7644a9ae 231 prompt_copy = OPENSSL_strdup(prompt);
0f113f3e
MC
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}
a63d5eaa 242
2d2ed9df 243int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
0f113f3e
MC
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}
2d2ed9df
RL
251
252int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
0f113f3e
MC
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) {
7644a9ae 262 prompt_copy = OPENSSL_strdup(prompt);
0f113f3e
MC
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) {
7644a9ae 270 action_desc_copy = OPENSSL_strdup(action_desc);
0f113f3e
MC
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) {
7644a9ae 278 ok_chars_copy = OPENSSL_strdup(ok_chars);
0f113f3e
MC
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) {
7644a9ae 286 cancel_chars_copy = OPENSSL_strdup(cancel_chars);
0f113f3e
MC
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);
2d2ed9df 296 err:
b548a1f1
RS
297 OPENSSL_free(prompt_copy);
298 OPENSSL_free(action_desc_copy);
299 OPENSSL_free(ok_chars_copy);
300 OPENSSL_free(cancel_chars_copy);
0f113f3e
MC
301 return -1;
302}
2d2ed9df 303
a63d5eaa 304int UI_add_info_string(UI *ui, const char *text)
0f113f3e
MC
305{
306 return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
307 NULL);
308}
a63d5eaa
RL
309
310int UI_dup_info_string(UI *ui, const char *text)
0f113f3e
MC
311{
312 char *text_copy = NULL;
313
314 if (text) {
7644a9ae 315 text_copy = OPENSSL_strdup(text);
0f113f3e
MC
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}
a63d5eaa
RL
325
326int UI_add_error_string(UI *ui, const char *text)
0f113f3e
MC
327{
328 return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
329 NULL);
330}
a63d5eaa
RL
331
332int UI_dup_error_string(UI *ui, const char *text)
0f113f3e
MC
333{
334 char *text_copy = NULL;
335
336 if (text) {
7644a9ae 337 text_copy = OPENSSL_strdup(text);
0f113f3e
MC
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}
9ad0f681
RL
346
347char *UI_construct_prompt(UI *ui, const char *object_desc,
0f113f3e
MC
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
b196e7d9 367 prompt = OPENSSL_malloc(len + 1);
0f113f3e
MC
368 if (prompt == NULL)
369 return NULL;
7644a9ae
RS
370 OPENSSL_strlcpy(prompt, prompt1, len + 1);
371 OPENSSL_strlcat(prompt, object_desc, len + 1);
0f113f3e 372 if (object_name) {
7644a9ae
RS
373 OPENSSL_strlcat(prompt, prompt2, len + 1);
374 OPENSSL_strlcat(prompt, object_name, len + 1);
0f113f3e 375 }
7644a9ae 376 OPENSSL_strlcat(prompt, prompt3, len + 1);
0f113f3e
MC
377 }
378 return prompt;
379}
a63d5eaa 380
1e7e62f8 381void *UI_add_user_data(UI *ui, void *user_data)
0f113f3e
MC
382{
383 void *old_data = ui->user_data;
384 ui->user_data = user_data;
385 return old_data;
386}
1e7e62f8
RL
387
388void *UI_get0_user_data(UI *ui)
0f113f3e
MC
389{
390 return ui->user_data;
391}
1e7e62f8 392
a63d5eaa 393const char *UI_get0_result(UI *ui, int i)
0f113f3e
MC
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}
a63d5eaa 405
2d2ed9df 406static int print_error(const char *str, size_t len, UI *ui)
0f113f3e
MC
407{
408 UI_STRING uis;
2d2ed9df 409
0f113f3e
MC
410 memset(&uis, 0, sizeof(uis));
411 uis.type = UIT_ERROR;
412 uis.out_string = str;
2d2ed9df 413
0f113f3e
MC
414 if (ui->meth->ui_write_string && !ui->meth->ui_write_string(ui, &uis))
415 return -1;
416 return 0;
417}
2d2ed9df 418
a63d5eaa 419int UI_process(UI *ui)
0f113f3e
MC
420{
421 int i, ok = 0;
2d2ed9df 422
0f113f3e
MC
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
476int 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:
a63d5eaa 484 {
0f113f3e
MC
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;
a63d5eaa 491 }
0f113f3e
MC
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
a63d5eaa 501int UI_set_ex_data(UI *r, int idx, void *arg)
0f113f3e
MC
502{
503 return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
504}
a63d5eaa
RL
505
506void *UI_get_ex_data(UI *r, int idx)
0f113f3e
MC
507{
508 return (CRYPTO_get_ex_data(&r->ex_data, idx));
509}
a63d5eaa
RL
510
511void UI_set_default_method(const UI_METHOD *meth)
0f113f3e
MC
512{
513 default_UI_meth = meth;
514}
a63d5eaa
RL
515
516const UI_METHOD *UI_get_default_method(void)
0f113f3e
MC
517{
518 if (default_UI_meth == NULL) {
519 default_UI_meth = UI_OpenSSL();
520 }
521 return default_UI_meth;
522}
a63d5eaa
RL
523
524const UI_METHOD *UI_get_method(UI *ui)
0f113f3e
MC
525{
526 return ui->meth;
527}
a63d5eaa
RL
528
529const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth)
0f113f3e
MC
530{
531 ui->meth = meth;
532 return ui->meth;
533}
a63d5eaa 534
9ad0f681 535UI_METHOD *UI_create_method(char *name)
0f113f3e 536{
b51bce94 537 UI_METHOD *ui_method = OPENSSL_zalloc(sizeof(*ui_method));
0f113f3e 538
90945fa3 539 if (ui_method != NULL)
7644a9ae 540 ui_method->name = OPENSSL_strdup(name);
0f113f3e
MC
541 return ui_method;
542}
543
544/*
545 * BIG FSCKING WARNING!!!! If you use this on a statically allocated method
546 * (that is, it hasn't been allocated using UI_create_method(), you deserve
547 * anything Murphy can throw at you and more! You have been warned.
548 */
eb929eef 549void UI_destroy_method(UI_METHOD *ui_method)
0f113f3e
MC
550{
551 OPENSSL_free(ui_method->name);
552 ui_method->name = NULL;
553 OPENSSL_free(ui_method);
554}
555
556int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui))
557{
558 if (method) {
559 method->ui_open_session = opener;
560 return 0;
561 } else
562 return -1;
563}
564
565int UI_method_set_writer(UI_METHOD *method,
566 int (*writer) (UI *ui, UI_STRING *uis))
567{
568 if (method) {
569 method->ui_write_string = writer;
570 return 0;
571 } else
572 return -1;
573}
574
575int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui))
576{
577 if (method) {
578 method->ui_flush = flusher;
579 return 0;
580 } else
581 return -1;
582}
583
584int UI_method_set_reader(UI_METHOD *method,
585 int (*reader) (UI *ui, UI_STRING *uis))
586{
587 if (method) {
588 method->ui_read_string = reader;
589 return 0;
590 } else
591 return -1;
592}
593
594int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui))
595{
596 if (method) {
597 method->ui_close_session = closer;
598 return 0;
599 } else
600 return -1;
601}
602
603int UI_method_set_prompt_constructor(UI_METHOD *method,
604 char *(*prompt_constructor) (UI *ui,
605 const char
606 *object_desc,
607 const char
608 *object_name))
609{
610 if (method) {
611 method->ui_construct_prompt = prompt_constructor;
612 return 0;
613 } else
614 return -1;
615}
616
617int (*UI_method_get_opener(UI_METHOD *method)) (UI *) {
618 if (method)
619 return method->ui_open_session;
620 else
621 return NULL;
622}
623
624int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *) {
625 if (method)
626 return method->ui_write_string;
627 else
628 return NULL;
629}
630
631int (*UI_method_get_flusher(UI_METHOD *method)) (UI *) {
632 if (method)
633 return method->ui_flush;
634 else
635 return NULL;
636}
637
638int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *) {
639 if (method)
640 return method->ui_read_string;
641 else
642 return NULL;
643}
644
645int (*UI_method_get_closer(UI_METHOD *method)) (UI *) {
646 if (method)
647 return method->ui_close_session;
648 else
649 return NULL;
650}
651
652char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
653 const char *,
654 const char *) {
655 if (method)
656 return method->ui_construct_prompt;
657 else
658 return NULL;
659}
a63d5eaa
RL
660
661enum UI_string_types UI_get_string_type(UI_STRING *uis)
0f113f3e
MC
662{
663 if (!uis)
664 return UIT_NONE;
665 return uis->type;
666}
a63d5eaa 667
9ad0f681 668int UI_get_input_flags(UI_STRING *uis)
0f113f3e
MC
669{
670 if (!uis)
671 return 0;
672 return uis->input_flags;
673}
9ad0f681 674
a63d5eaa 675const char *UI_get0_output_string(UI_STRING *uis)
0f113f3e
MC
676{
677 if (!uis)
678 return NULL;
679 return uis->out_string;
680}
a63d5eaa 681
2d2ed9df 682const char *UI_get0_action_string(UI_STRING *uis)
0f113f3e
MC
683{
684 if (!uis)
685 return NULL;
686 switch (uis->type) {
687 case UIT_PROMPT:
688 case UIT_BOOLEAN:
689 return uis->_.boolean_data.action_desc;
690 default:
691 return NULL;
692 }
693}
2d2ed9df 694
a63d5eaa 695const char *UI_get0_result_string(UI_STRING *uis)
0f113f3e
MC
696{
697 if (!uis)
698 return NULL;
699 switch (uis->type) {
700 case UIT_PROMPT:
701 case UIT_VERIFY:
702 return uis->result_buf;
703 default:
704 return NULL;
705 }
706}
a63d5eaa
RL
707
708const char *UI_get0_test_string(UI_STRING *uis)
0f113f3e
MC
709{
710 if (!uis)
711 return NULL;
712 switch (uis->type) {
713 case UIT_VERIFY:
714 return uis->_.string_data.test_buf;
715 default:
716 return NULL;
717 }
718}
a63d5eaa
RL
719
720int UI_get_result_minsize(UI_STRING *uis)
0f113f3e
MC
721{
722 if (!uis)
723 return -1;
724 switch (uis->type) {
725 case UIT_PROMPT:
726 case UIT_VERIFY:
727 return uis->_.string_data.result_minsize;
728 default:
729 return -1;
730 }
731}
a63d5eaa
RL
732
733int UI_get_result_maxsize(UI_STRING *uis)
0f113f3e
MC
734{
735 if (!uis)
736 return -1;
737 switch (uis->type) {
738 case UIT_PROMPT:
739 case UIT_VERIFY:
740 return uis->_.string_data.result_maxsize;
741 default:
742 return -1;
743 }
744}
a63d5eaa 745
2d2ed9df 746int UI_set_result(UI *ui, UI_STRING *uis, const char *result)
0f113f3e
MC
747{
748 int l = strlen(result);
749
750 ui->flags &= ~UI_FLAG_REDOABLE;
751
752 if (!uis)
753 return -1;
754 switch (uis->type) {
755 case UIT_PROMPT:
756 case UIT_VERIFY:
757 {
758 char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize) + 1];
759 char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize) + 1];
760
761 BIO_snprintf(number1, sizeof(number1), "%d",
762 uis->_.string_data.result_minsize);
763 BIO_snprintf(number2, sizeof(number2), "%d",
764 uis->_.string_data.result_maxsize);
765
766 if (l < uis->_.string_data.result_minsize) {
767 ui->flags |= UI_FLAG_REDOABLE;
768 UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_SMALL);
769 ERR_add_error_data(5, "You must type in ",
770 number1, " to ", number2, " characters");
771 return -1;
772 }
773 if (l > uis->_.string_data.result_maxsize) {
774 ui->flags |= UI_FLAG_REDOABLE;
775 UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_LARGE);
776 ERR_add_error_data(5, "You must type in ",
777 number1, " to ", number2, " characters");
778 return -1;
779 }
780 }
781
782 if (!uis->result_buf) {
783 UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
784 return -1;
785 }
786
7644a9ae 787 OPENSSL_strlcpy(uis->result_buf, result,
0f113f3e
MC
788 uis->_.string_data.result_maxsize + 1);
789 break;
790 case UIT_BOOLEAN:
791 {
792 const char *p;
793
794 if (!uis->result_buf) {
795 UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
796 return -1;
797 }
798
799 uis->result_buf[0] = '\0';
800 for (p = result; *p; p++) {
801 if (strchr(uis->_.boolean_data.ok_chars, *p)) {
802 uis->result_buf[0] = uis->_.boolean_data.ok_chars[0];
803 break;
804 }
805 if (strchr(uis->_.boolean_data.cancel_chars, *p)) {
806 uis->result_buf[0] = uis->_.boolean_data.cancel_chars[0];
807 break;
808 }
809 }
810 }
811 default:
812 break;
813 }
814 return 0;
815}