Coverage Report

Created: 2025-03-09 06:52

/src/libressl/crypto/ui/ui_lib.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: ui_lib.c,v 1.51 2023/02/16 08:38:17 tb Exp $ */
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
61
#include <openssl/opensslconf.h>
62
63
#include <openssl/buffer.h>
64
#include <openssl/err.h>
65
#include <openssl/ui.h>
66
67
#include "ui_local.h"
68
69
static const UI_METHOD *default_UI_meth = NULL;
70
71
UI *
72
UI_new(void)
73
0
{
74
0
  return (UI_new_method(NULL));
75
0
}
76
LCRYPTO_ALIAS(UI_new);
77
78
UI *
79
UI_new_method(const UI_METHOD *method)
80
0
{
81
0
  UI *ret;
82
83
0
  if ((ret = calloc(1, sizeof(UI))) == NULL) {
84
0
    UIerror(ERR_R_MALLOC_FAILURE);
85
0
    return NULL;
86
0
  }
87
0
  if ((ret->meth = method) == NULL)
88
0
    ret->meth = UI_get_default_method();
89
0
  CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data);
90
91
0
  return ret;
92
0
}
93
LCRYPTO_ALIAS(UI_new_method);
94
95
static void
96
free_string(UI_STRING *uis)
97
0
{
98
0
  if (uis == NULL)
99
0
    return;
100
0
  if (uis->flags & OUT_STRING_FREEABLE) {
101
0
    free((char *) uis->out_string);
102
0
    switch (uis->type) {
103
0
    case UIT_BOOLEAN:
104
0
      free((char *)uis->_.boolean_data.action_desc);
105
0
      free((char *)uis->_.boolean_data.ok_chars);
106
0
      free((char *)uis->_.boolean_data.cancel_chars);
107
0
      break;
108
0
    default:
109
0
      break;
110
0
    }
111
0
  }
112
0
  free(uis);
113
0
}
114
115
void
116
UI_free(UI *ui)
117
0
{
118
0
  if (ui == NULL)
119
0
    return;
120
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
  free(ui);
124
0
}
125
LCRYPTO_ALIAS(UI_free);
126
127
static int
128
allocate_string_stack(UI *ui)
129
0
{
130
0
  if (ui->strings == NULL) {
131
0
    if ((ui->strings = sk_UI_STRING_new_null()) == NULL) {
132
0
      UIerror(ERR_R_MALLOC_FAILURE);
133
0
      return -1;
134
0
    }
135
0
  }
136
0
  return 0;
137
0
}
138
139
static UI_STRING *
140
general_allocate_prompt(const char *prompt, int dup_prompt,
141
    enum UI_string_types type, int input_flags, char *result_buf)
142
0
{
143
0
  UI_STRING *uis = NULL;
144
145
0
  if (prompt == NULL) {
146
0
    UIerror(ERR_R_PASSED_NULL_PARAMETER);
147
0
    goto err;
148
0
  }
149
0
  if ((type == UIT_PROMPT || type == UIT_VERIFY || type == UIT_BOOLEAN) &&
150
0
      result_buf == NULL) {
151
0
    UIerror(UI_R_NO_RESULT_BUFFER);
152
0
    goto err;
153
0
  }
154
155
0
  if ((uis = calloc(1, sizeof(UI_STRING))) == NULL) {
156
0
    UIerror(ERR_R_MALLOC_FAILURE);
157
0
    goto err;
158
0
  }
159
0
  uis->out_string = prompt;
160
0
  if (dup_prompt) {
161
0
    if ((uis->out_string = strdup(prompt)) == NULL) {
162
0
      UIerror(ERR_R_MALLOC_FAILURE);
163
0
      goto err;
164
0
    }
165
0
    uis->flags = OUT_STRING_FREEABLE;
166
0
  }
167
0
  uis->input_flags = input_flags;
168
0
  uis->type = type;
169
0
  uis->result_buf = result_buf;
170
171
0
  return uis;
172
173
0
 err:
174
0
  free_string(uis);
175
0
  return NULL;
176
0
}
177
178
static int
179
general_allocate_string(UI *ui, const char *prompt, int dup_prompt,
180
    enum UI_string_types type, int input_flags, char *result_buf, int minsize,
181
    int maxsize, const char *test_buf)
182
0
{
183
0
  UI_STRING *s;
184
0
  int ret;
185
186
0
  if ((s = general_allocate_prompt(prompt, dup_prompt, type, input_flags,
187
0
      result_buf)) == NULL)
188
0
    goto err;
189
0
  s->_.string_data.result_minsize = minsize;
190
0
  s->_.string_data.result_maxsize = maxsize;
191
0
  s->_.string_data.test_buf = test_buf;
192
193
0
  if (allocate_string_stack(ui) < 0)
194
0
    goto err;
195
0
  if ((ret = sk_UI_STRING_push(ui->strings, s)) <= 0)
196
0
    goto err;
197
198
0
  return ret;
199
200
0
 err:
201
0
  free_string(s);
202
0
  return -1;
203
0
}
204
205
static int
206
general_allocate_boolean(UI *ui, const char *prompt, const char *action_desc,
207
    const char *ok_chars, const char *cancel_chars, int dup_strings,
208
    enum UI_string_types type, int input_flags, char *result_buf)
209
0
{
210
0
  UI_STRING *s = NULL;
211
0
  int ret;
212
213
0
  if (ok_chars == NULL || cancel_chars == NULL) {
214
0
    UIerror(ERR_R_PASSED_NULL_PARAMETER);
215
0
    goto err;
216
0
  }
217
0
  if (ok_chars[strcspn(ok_chars, cancel_chars)] != '\0') {
218
0
    UIerror(UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
219
0
    goto err;
220
0
  }
221
222
0
  if ((s = general_allocate_prompt(prompt, dup_strings, type, input_flags,
223
0
      result_buf)) == NULL)
224
0
    goto err;
225
226
0
  if (dup_strings) {
227
0
    if (action_desc != NULL) {
228
0
      if ((s->_.boolean_data.action_desc =
229
0
          strdup(action_desc)) == NULL) {
230
0
        UIerror(ERR_R_MALLOC_FAILURE);
231
0
        goto err;
232
0
      }
233
0
    }
234
0
    if ((s->_.boolean_data.ok_chars = strdup(ok_chars)) == NULL) {
235
0
      UIerror(ERR_R_MALLOC_FAILURE);
236
0
      goto err;
237
0
    }
238
0
    if ((s->_.boolean_data.cancel_chars = strdup(cancel_chars)) ==
239
0
        NULL) {
240
0
      UIerror(ERR_R_MALLOC_FAILURE);
241
0
      goto err;
242
0
    }
243
0
  } else {
244
0
    s->_.boolean_data.action_desc = action_desc;
245
0
    s->_.boolean_data.ok_chars = ok_chars;
246
0
    s->_.boolean_data.cancel_chars = cancel_chars;
247
0
  }
248
249
0
  if (allocate_string_stack(ui) < 0)
250
0
    goto err;
251
0
  if ((ret = sk_UI_STRING_push(ui->strings, s)) <= 0)
252
0
    goto err;
253
254
0
  return ret;
255
256
0
 err:
257
0
  free_string(s);
258
0
  return -1;
259
0
}
260
261
/*
262
 * Returns the index to the place in the stack or -1 for error.  Uses a
263
 * direct reference to the prompt.
264
 */
265
int
266
UI_add_input_string(UI *ui, const char *prompt, int flags, char *result_buf,
267
    int minsize, int maxsize)
268
0
{
269
0
  return general_allocate_string(ui, prompt, 0, UIT_PROMPT, flags,
270
0
      result_buf, minsize, maxsize, NULL);
271
0
}
272
LCRYPTO_ALIAS(UI_add_input_string);
273
274
/* Same as UI_add_input_string(), excepts it takes a copy of the prompt. */
275
int
276
UI_dup_input_string(UI *ui, const char *prompt, int flags, char *result_buf,
277
    int minsize, int maxsize)
278
0
{
279
0
  return general_allocate_string(ui, prompt, 1, UIT_PROMPT, flags,
280
0
      result_buf, minsize, maxsize, NULL);
281
0
}
282
LCRYPTO_ALIAS(UI_dup_input_string);
283
284
int
285
UI_add_verify_string(UI *ui, const char *prompt, int flags, char *result_buf,
286
    int minsize, int maxsize, const char *test_buf)
287
0
{
288
0
  return general_allocate_string(ui, prompt, 0, UIT_VERIFY, flags,
289
0
      result_buf, minsize, maxsize, test_buf);
290
0
}
291
LCRYPTO_ALIAS(UI_add_verify_string);
292
293
int
294
UI_dup_verify_string(UI *ui, const char *prompt, int flags,
295
    char *result_buf, int minsize, int maxsize, const char *test_buf)
296
0
{
297
0
  return general_allocate_string(ui, prompt, 1, UIT_VERIFY, flags,
298
0
      result_buf, minsize, maxsize, test_buf);
299
0
}
300
LCRYPTO_ALIAS(UI_dup_verify_string);
301
302
int
303
UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
304
    const char *ok_chars, const char *cancel_chars, int flags, char *result_buf)
305
0
{
306
0
  return general_allocate_boolean(ui, prompt, action_desc, ok_chars,
307
0
      cancel_chars, 0, UIT_BOOLEAN, flags, result_buf);
308
0
}
309
LCRYPTO_ALIAS(UI_add_input_boolean);
310
311
int
312
UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
313
    const char *ok_chars, const char *cancel_chars, int flags, char *result_buf)
314
0
{
315
0
  return general_allocate_boolean(ui, prompt, action_desc, ok_chars,
316
0
      cancel_chars, 1, UIT_BOOLEAN, flags, result_buf);
317
0
}
318
LCRYPTO_ALIAS(UI_dup_input_boolean);
319
320
int
321
UI_add_info_string(UI *ui, const char *text)
322
0
{
323
0
  return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
324
0
      NULL);
325
0
}
326
LCRYPTO_ALIAS(UI_add_info_string);
327
328
int
329
UI_dup_info_string(UI *ui, const char *text)
330
0
{
331
0
  return general_allocate_string(ui, text, 1, UIT_INFO, 0, NULL, 0, 0,
332
0
      NULL);
333
0
}
334
LCRYPTO_ALIAS(UI_dup_info_string);
335
336
int
337
UI_add_error_string(UI *ui, const char *text)
338
0
{
339
0
  return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
340
0
      NULL);
341
0
}
342
LCRYPTO_ALIAS(UI_add_error_string);
343
344
int
345
UI_dup_error_string(UI *ui, const char *text)
346
0
{
347
0
  return general_allocate_string(ui, text, 1, UIT_ERROR, 0, NULL, 0, 0,
348
0
      NULL);
349
0
}
350
LCRYPTO_ALIAS(UI_dup_error_string);
351
352
char *
353
UI_construct_prompt(UI *ui, const char *object_desc, const char *object_name)
354
0
{
355
0
  char *prompt;
356
357
0
  if (ui->meth->ui_construct_prompt)
358
0
    return ui->meth->ui_construct_prompt(ui, object_desc,
359
0
        object_name);
360
361
0
  if (object_desc == NULL)
362
0
    return NULL;
363
364
0
  if (object_name == NULL) {
365
0
    if (asprintf(&prompt, "Enter %s:", object_desc) == -1)
366
0
      return (NULL);
367
0
  } else {
368
0
    if (asprintf(&prompt, "Enter %s for %s:", object_desc,
369
0
        object_name) == -1)
370
0
      return (NULL);
371
0
  }
372
373
0
  return prompt;
374
0
}
375
LCRYPTO_ALIAS(UI_construct_prompt);
376
377
void *
378
UI_add_user_data(UI *ui, void *user_data)
379
0
{
380
0
  void *old_data = ui->user_data;
381
382
0
  ui->user_data = user_data;
383
384
0
  return old_data;
385
0
}
386
LCRYPTO_ALIAS(UI_add_user_data);
387
388
void *
389
UI_get0_user_data(UI *ui)
390
0
{
391
0
  return ui->user_data;
392
0
}
393
LCRYPTO_ALIAS(UI_get0_user_data);
394
395
const char *
396
UI_get0_result(UI *ui, int i)
397
0
{
398
0
  if (i < 0) {
399
0
    UIerror(UI_R_INDEX_TOO_SMALL);
400
0
    return NULL;
401
0
  }
402
0
  if (i >= sk_UI_STRING_num(ui->strings)) {
403
0
    UIerror(UI_R_INDEX_TOO_LARGE);
404
0
    return NULL;
405
0
  }
406
0
  return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
407
0
}
408
LCRYPTO_ALIAS(UI_get0_result);
409
410
static int
411
print_error(const char *str, size_t len, void *arg)
412
0
{
413
0
  UI *ui = arg;
414
0
  UI_STRING uis;
415
416
0
  memset(&uis, 0, sizeof(uis));
417
0
  uis.type = UIT_ERROR;
418
0
  uis.out_string = str;
419
420
0
  if (ui->meth->ui_write_string &&
421
0
      !ui->meth->ui_write_string(ui, &uis))
422
0
    return -1;
423
0
  return 0;
424
0
}
425
426
int
427
UI_process(UI *ui)
428
0
{
429
0
  int i, ok = 0;
430
431
0
  if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
432
0
    return -1;
433
434
0
  if (ui->flags & UI_FLAG_PRINT_ERRORS)
435
0
    ERR_print_errors_cb(print_error, ui);
436
437
0
  for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
438
0
    if (ui->meth->ui_write_string &&
439
0
        !ui->meth->ui_write_string(ui,
440
0
      sk_UI_STRING_value(ui->strings, i))) {
441
0
      ok = -1;
442
0
      goto err;
443
0
    }
444
0
  }
445
446
0
  if (ui->meth->ui_flush)
447
0
    switch (ui->meth->ui_flush(ui)) {
448
0
    case -1:  /* Interrupt/Cancel/something... */
449
0
      ok = -2;
450
0
      goto err;
451
0
    case 0:   /* Errors */
452
0
      ok = -1;
453
0
      goto err;
454
0
    default:  /* Success */
455
0
      ok = 0;
456
0
      break;
457
0
    }
458
459
0
  for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
460
0
    if (ui->meth->ui_read_string) {
461
0
      switch (ui->meth->ui_read_string(ui,
462
0
          sk_UI_STRING_value(ui->strings, i))) {
463
0
      case -1:  /* Interrupt/Cancel/something... */
464
0
        ui->flags &= ~UI_FLAG_REDOABLE;
465
0
        ok = -2;
466
0
        goto err;
467
0
      case 0:   /* Errors */
468
0
        ok = -1;
469
0
        goto err;
470
0
      default:  /* Success */
471
0
        ok = 0;
472
0
        break;
473
0
      }
474
0
    }
475
0
  }
476
477
0
 err:
478
0
  if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
479
0
    return -1;
480
0
  return ok;
481
0
}
482
LCRYPTO_ALIAS(UI_process);
483
484
int
485
UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void))
486
0
{
487
0
  if (ui == NULL) {
488
0
    UIerror(ERR_R_PASSED_NULL_PARAMETER);
489
0
    return -1;
490
0
  }
491
492
0
  switch (cmd) {
493
0
  case UI_CTRL_PRINT_ERRORS:
494
0
    {
495
0
      int save_flag = !!(ui->flags & UI_FLAG_PRINT_ERRORS);
496
0
      if (i)
497
0
        ui->flags |= UI_FLAG_PRINT_ERRORS;
498
0
      else
499
0
        ui->flags &= ~UI_FLAG_PRINT_ERRORS;
500
0
      return save_flag;
501
0
    }
502
0
  case UI_CTRL_IS_REDOABLE:
503
0
    return !!(ui->flags & UI_FLAG_REDOABLE);
504
0
  default:
505
0
    break;
506
0
  }
507
0
  UIerror(UI_R_UNKNOWN_CONTROL_COMMAND);
508
0
  return -1;
509
0
}
510
LCRYPTO_ALIAS(UI_ctrl);
511
512
int
513
UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
514
    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
515
0
{
516
0
  return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp,
517
0
      new_func, dup_func, free_func);
518
0
}
519
LCRYPTO_ALIAS(UI_get_ex_new_index);
520
521
int
522
UI_set_ex_data(UI *r, int idx, void *arg)
523
0
{
524
0
  return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
525
0
}
526
LCRYPTO_ALIAS(UI_set_ex_data);
527
528
void *
529
UI_get_ex_data(UI *r, int idx)
530
0
{
531
0
  return (CRYPTO_get_ex_data(&r->ex_data, idx));
532
0
}
533
LCRYPTO_ALIAS(UI_get_ex_data);
534
535
void
536
UI_set_default_method(const UI_METHOD *method)
537
0
{
538
0
  default_UI_meth = method;
539
0
}
540
LCRYPTO_ALIAS(UI_set_default_method);
541
542
const UI_METHOD *
543
UI_get_default_method(void)
544
0
{
545
0
  if (default_UI_meth == NULL)
546
0
    default_UI_meth = UI_OpenSSL();
547
548
0
  return default_UI_meth;
549
0
}
550
LCRYPTO_ALIAS(UI_get_default_method);
551
552
const UI_METHOD *
553
UI_get_method(UI *ui)
554
0
{
555
0
  return ui->meth;
556
0
}
557
LCRYPTO_ALIAS(UI_get_method);
558
559
const UI_METHOD *
560
UI_set_method(UI *ui, const UI_METHOD *method)
561
0
{
562
0
  ui->meth = method;
563
564
0
  return ui->meth;
565
0
}
566
LCRYPTO_ALIAS(UI_set_method);
567
568
UI_METHOD *
569
UI_create_method(const char *name)
570
0
{
571
0
  UI_METHOD *method = NULL;
572
573
0
  if ((method = calloc(1, sizeof(UI_METHOD))) == NULL)
574
0
    goto err;
575
576
0
  if (name != NULL) {
577
0
    if ((method->name = strdup(name)) == NULL)
578
0
      goto err;
579
0
  }
580
581
0
  return method;
582
583
0
 err:
584
0
  UI_destroy_method(method);
585
586
0
  return NULL;
587
0
}
588
LCRYPTO_ALIAS(UI_create_method);
589
590
void
591
UI_destroy_method(UI_METHOD *method)
592
0
{
593
0
  if (method == NULL)
594
0
    return;
595
596
0
  free(method->name);
597
0
  free(method);
598
0
}
599
LCRYPTO_ALIAS(UI_destroy_method);
600
601
int
602
UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui))
603
0
{
604
0
  if (method == NULL)
605
0
    return -1;
606
607
0
  method->ui_open_session = opener;
608
609
0
  return 0;
610
0
}
611
LCRYPTO_ALIAS(UI_method_set_opener);
612
613
int
614
UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis))
615
0
{
616
0
  if (method == NULL)
617
0
    return -1;
618
619
0
  method->ui_write_string = writer;
620
621
0
  return 0;
622
0
}
623
LCRYPTO_ALIAS(UI_method_set_writer);
624
625
int
626
UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui))
627
0
{
628
0
  if (method == NULL)
629
0
    return -1;
630
631
0
  method->ui_flush = flusher;
632
633
0
  return 0;
634
0
}
635
LCRYPTO_ALIAS(UI_method_set_flusher);
636
637
int
638
UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis))
639
0
{
640
0
  if (method == NULL)
641
0
    return -1;
642
643
0
  method->ui_read_string = reader;
644
645
0
  return 0;
646
0
}
647
LCRYPTO_ALIAS(UI_method_set_reader);
648
649
int
650
UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui))
651
0
{
652
0
  if (method == NULL)
653
0
    return -1;
654
655
0
  method->ui_close_session = closer;
656
657
0
  return 0;
658
0
}
659
LCRYPTO_ALIAS(UI_method_set_closer);
660
661
int
662
UI_method_set_prompt_constructor(UI_METHOD *method,
663
    char *(*prompt_constructor)(UI *ui, const char *object_desc,
664
    const char *object_name))
665
0
{
666
0
  if (method == NULL)
667
0
    return -1;
668
669
0
  method->ui_construct_prompt = prompt_constructor;
670
671
0
  return 0;
672
0
}
673
LCRYPTO_ALIAS(UI_method_set_prompt_constructor);
674
675
int
676
(*UI_method_get_opener(const UI_METHOD * method))(UI *)
677
0
{
678
0
  if (method == NULL)
679
0
    return NULL;
680
681
0
  return method->ui_open_session;
682
0
}
683
LCRYPTO_ALIAS(UI_method_get_opener);
684
685
int
686
(*UI_method_get_writer(const UI_METHOD *method))(UI *, UI_STRING *)
687
0
{
688
0
  if (method == NULL)
689
0
    return NULL;
690
691
0
  return method->ui_write_string;
692
0
}
693
LCRYPTO_ALIAS(UI_method_get_writer);
694
695
int
696
(*UI_method_get_flusher(const UI_METHOD *method)) (UI *)
697
0
{
698
0
  if (method == NULL)
699
0
    return NULL;
700
701
0
  return method->ui_flush;
702
0
}
703
LCRYPTO_ALIAS(UI_method_get_flusher);
704
705
int
706
(*UI_method_get_reader(const UI_METHOD *method))(UI *, UI_STRING *)
707
0
{
708
0
  if (method == NULL)
709
0
    return NULL;
710
711
0
  return method->ui_read_string;
712
0
}
713
LCRYPTO_ALIAS(UI_method_get_reader);
714
715
int
716
(*UI_method_get_closer(const UI_METHOD *method))(UI *)
717
0
{
718
0
  if (method == NULL)
719
0
    return NULL;
720
721
0
  return method->ui_close_session;
722
0
}
723
LCRYPTO_ALIAS(UI_method_get_closer);
724
725
char *
726
(*UI_method_get_prompt_constructor(const UI_METHOD *method))(UI *, const char *,
727
    const char *)
728
0
{
729
0
  if (method == NULL)
730
0
    return NULL;
731
732
0
  return method->ui_construct_prompt;
733
0
}
734
LCRYPTO_ALIAS(UI_method_get_prompt_constructor);
735
736
enum UI_string_types
737
UI_get_string_type(UI_STRING *uis)
738
0
{
739
0
  if (uis == NULL)
740
0
    return UIT_NONE;
741
742
0
  return uis->type;
743
0
}
744
LCRYPTO_ALIAS(UI_get_string_type);
745
746
int
747
UI_get_input_flags(UI_STRING *uis)
748
0
{
749
0
  if (uis == NULL)
750
0
    return 0;
751
752
0
  return uis->input_flags;
753
0
}
754
LCRYPTO_ALIAS(UI_get_input_flags);
755
756
const char *
757
UI_get0_output_string(UI_STRING *uis)
758
0
{
759
0
  if (uis == NULL)
760
0
    return NULL;
761
762
0
  return uis->out_string;
763
0
}
764
LCRYPTO_ALIAS(UI_get0_output_string);
765
766
const char *
767
UI_get0_action_string(UI_STRING *uis)
768
0
{
769
0
  if (uis == NULL)
770
0
    return NULL;
771
772
0
  switch (uis->type) {
773
0
  case UIT_PROMPT:
774
0
  case UIT_BOOLEAN:
775
0
    return uis->_.boolean_data.action_desc;
776
0
  default:
777
0
    return NULL;
778
0
  }
779
0
}
780
LCRYPTO_ALIAS(UI_get0_action_string);
781
782
const char *
783
UI_get0_result_string(UI_STRING *uis)
784
0
{
785
0
  if (uis == NULL)
786
0
    return NULL;
787
788
0
  switch (uis->type) {
789
0
  case UIT_PROMPT:
790
0
  case UIT_VERIFY:
791
0
    return uis->result_buf;
792
0
  default:
793
0
    return NULL;
794
0
  }
795
0
}
796
LCRYPTO_ALIAS(UI_get0_result_string);
797
798
const char *
799
UI_get0_test_string(UI_STRING *uis)
800
0
{
801
0
  if (uis == NULL)
802
0
    return NULL;
803
804
0
  switch (uis->type) {
805
0
  case UIT_VERIFY:
806
0
    return uis->_.string_data.test_buf;
807
0
  default:
808
0
    return NULL;
809
0
  }
810
0
}
811
LCRYPTO_ALIAS(UI_get0_test_string);
812
813
int
814
UI_get_result_minsize(UI_STRING *uis)
815
0
{
816
0
  if (uis == NULL)
817
0
    return -1;
818
819
0
  switch (uis->type) {
820
0
  case UIT_PROMPT:
821
0
  case UIT_VERIFY:
822
0
    return uis->_.string_data.result_minsize;
823
0
  default:
824
0
    return -1;
825
0
  }
826
0
}
827
LCRYPTO_ALIAS(UI_get_result_minsize);
828
829
int
830
UI_get_result_maxsize(UI_STRING *uis)
831
0
{
832
0
  if (uis == NULL)
833
0
    return -1;
834
835
0
  switch (uis->type) {
836
0
  case UIT_PROMPT:
837
0
  case UIT_VERIFY:
838
0
    return uis->_.string_data.result_maxsize;
839
0
  default:
840
0
    return -1;
841
0
  }
842
0
}
843
LCRYPTO_ALIAS(UI_get_result_maxsize);
844
845
int
846
UI_set_result(UI *ui, UI_STRING *uis, const char *result)
847
0
{
848
0
  const char *p;
849
0
  int l = strlen(result);
850
851
0
  ui->flags &= ~UI_FLAG_REDOABLE;
852
853
0
  if (uis == NULL)
854
0
    return -1;
855
856
0
  switch (uis->type) {
857
0
  case UIT_PROMPT:
858
0
  case UIT_VERIFY:
859
0
    if (l < uis->_.string_data.result_minsize) {
860
0
      ui->flags |= UI_FLAG_REDOABLE;
861
0
      UIerror(UI_R_RESULT_TOO_SMALL);
862
0
      ERR_asprintf_error_data
863
0
          ("You must type in %d to %d characters",
864
0
        uis->_.string_data.result_minsize,
865
0
        uis->_.string_data.result_maxsize);
866
0
      return -1;
867
0
    }
868
0
    if (l > uis->_.string_data.result_maxsize) {
869
0
      ui->flags |= UI_FLAG_REDOABLE;
870
0
      UIerror(UI_R_RESULT_TOO_LARGE);
871
0
      ERR_asprintf_error_data
872
0
          ("You must type in %d to %d characters",
873
0
        uis->_.string_data.result_minsize,
874
0
        uis->_.string_data.result_maxsize);
875
0
      return -1;
876
0
    }
877
0
    if (!uis->result_buf) {
878
0
      UIerror(UI_R_NO_RESULT_BUFFER);
879
0
      return -1;
880
0
    }
881
0
    strlcpy(uis->result_buf, result,
882
0
        uis->_.string_data.result_maxsize + 1);
883
0
    break;
884
0
  case UIT_BOOLEAN:
885
0
    if (!uis->result_buf) {
886
0
      UIerror(UI_R_NO_RESULT_BUFFER);
887
0
      return -1;
888
0
    }
889
0
    uis->result_buf[0] = '\0';
890
0
    for (p = result; *p; p++) {
891
0
      if (strchr(uis->_.boolean_data.ok_chars, *p)) {
892
0
        uis->result_buf[0] =
893
0
            uis->_.boolean_data.ok_chars[0];
894
0
        break;
895
0
      }
896
0
      if (strchr(uis->_.boolean_data.cancel_chars, *p)) {
897
0
        uis->result_buf[0] =
898
0
            uis->_.boolean_data.cancel_chars[0];
899
0
        break;
900
0
      }
901
0
    }
902
0
  default:
903
0
    break;
904
0
  }
905
0
  return 0;
906
0
}
907
LCRYPTO_ALIAS(UI_set_result);