Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/ui/ui_lib.c
Line
Count
Source (jump to first uncovered line)
1
/* crypto/ui/ui_lib.c */
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
UI *UI_new(void)
73
0
{
74
0
    return (UI_new_method(NULL));
75
0
}
76
77
UI *UI_new_method(const UI_METHOD *method)
78
0
{
79
0
    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
0
    }
86
0
    if (method == NULL)
87
0
        ret->meth = UI_get_default_method();
88
0
    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
0
}
97
98
static void free_string(UI_STRING *uis)
99
0
{
100
0
    if (uis->flags & OUT_STRING_FREEABLE) {
101
0
        OPENSSL_free((char *)uis->out_string);
102
0
        switch (uis->type) {
103
0
        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
0
        default:
109
0
            break;
110
0
        }
111
0
    }
112
0
    OPENSSL_free(uis);
113
0
}
114
115
void UI_free(UI *ui)
116
0
{
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
0
}
123
124
static int allocate_string_stack(UI *ui)
125
0
{
126
0
    if (ui->strings == NULL) {
127
0
        ui->strings = sk_UI_STRING_new_null();
128
0
        if (ui->strings == NULL) {
129
0
            return -1;
130
0
        }
131
0
    }
132
0
    return 0;
133
0
}
134
135
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
0
{
140
0
    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
0
    }
154
0
    return ret;
155
0
}
156
157
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
0
{
163
0
    int ret = -1;
164
0
    UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
165
0
                                           type, input_flags, result_buf);
166
167
0
    if (s != NULL) {
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
0
        } else
177
0
            free_string(s);
178
0
    }
179
0
    return ret;
180
0
}
181
182
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
0
{
191
0
    int ret = -1;
192
0
    UI_STRING *s;
193
0
    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
0
    } else {
200
0
        for (p = ok_chars; *p != '\0'; p++) {
201
0
            if (strchr(cancel_chars, *p) != NULL) {
202
0
                UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
203
0
                      UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
204
0
            }
205
0
        }
206
207
0
        s = general_allocate_prompt(ui, prompt, prompt_freeable,
208
0
                                    type, input_flags, result_buf);
209
210
0
        if (s != NULL) {
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
0
            } else
222
0
                free_string(s);
223
0
        }
224
0
    }
225
0
    return ret;
226
0
}
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
int UI_add_input_string(UI *ui, const char *prompt, int flags,
233
                        char *result_buf, int minsize, int maxsize)
234
0
{
235
0
    return general_allocate_string(ui, prompt, 0,
236
0
                                   UIT_PROMPT, flags, result_buf, minsize,
237
0
                                   maxsize, NULL);
238
0
}
239
240
/* Same as UI_add_input_string(), excepts it takes a copy of the prompt */
241
int UI_dup_input_string(UI *ui, const char *prompt, int flags,
242
                        char *result_buf, int minsize, int maxsize)
243
0
{
244
0
    char *prompt_copy = NULL;
245
246
0
    if (prompt != NULL) {
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
0
        }
252
0
    }
253
254
0
    return general_allocate_string(ui, prompt_copy, 1,
255
0
                                   UIT_PROMPT, flags, result_buf, minsize,
256
0
                                   maxsize, NULL);
257
0
}
258
259
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
0
{
263
0
    return general_allocate_string(ui, prompt, 0,
264
0
                                   UIT_VERIFY, flags, result_buf, minsize,
265
0
                                   maxsize, test_buf);
266
0
}
267
268
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
0
{
272
0
    char *prompt_copy = NULL;
273
274
0
    if (prompt != NULL) {
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
0
        }
280
0
    }
281
282
0
    return general_allocate_string(ui, prompt_copy, 1,
283
0
                                   UIT_VERIFY, flags, result_buf, minsize,
284
0
                                   maxsize, test_buf);
285
0
}
286
287
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
0
{
291
0
    return general_allocate_boolean(ui, prompt, action_desc,
292
0
                                    ok_chars, cancel_chars, 0, UIT_BOOLEAN,
293
0
                                    flags, result_buf);
294
0
}
295
296
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
0
{
300
0
    char *prompt_copy = NULL;
301
0
    char *action_desc_copy = NULL;
302
0
    char *ok_chars_copy = NULL;
303
0
    char *cancel_chars_copy = NULL;
304
305
0
    if (prompt != NULL) {
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
0
        }
311
0
    }
312
313
0
    if (action_desc != NULL) {
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
0
        }
319
0
    }
320
321
0
    if (ok_chars != NULL) {
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
0
        }
327
0
    }
328
329
0
    if (cancel_chars != NULL) {
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
0
        }
335
0
    }
336
337
0
    return general_allocate_boolean(ui, prompt_copy, action_desc_copy,
338
0
                                    ok_chars_copy, cancel_chars_copy, 1,
339
0
                                    UIT_BOOLEAN, flags, result_buf);
340
0
 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
0
    return -1;
350
0
}
351
352
int UI_add_info_string(UI *ui, const char *text)
353
0
{
354
0
    return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
355
0
                                   NULL);
356
0
}
357
358
int UI_dup_info_string(UI *ui, const char *text)
359
0
{
360
0
    char *text_copy = NULL;
361
362
0
    if (text != NULL) {
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
0
        }
368
0
    }
369
370
0
    return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
371
0
                                   0, 0, NULL);
372
0
}
373
374
int UI_add_error_string(UI *ui, const char *text)
375
0
{
376
0
    return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
377
0
                                   NULL);
378
0
}
379
380
int UI_dup_error_string(UI *ui, const char *text)
381
0
{
382
0
    char *text_copy = NULL;
383
384
0
    if (text != NULL) {
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
0
        }
390
0
    }
391
0
    return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL,
392
0
                                   0, 0, NULL);
393
0
}
394
395
char *UI_construct_prompt(UI *ui, const char *object_desc,
396
                          const char *object_name)
397
0
{
398
0
    char *prompt = NULL;
399
400
0
    if (ui->meth->ui_construct_prompt != NULL)
401
0
        prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name);
402
0
    else {
403
0
        char prompt1[] = "Enter ";
404
0
        char prompt2[] = " for ";
405
0
        char prompt3[] = ":";
406
0
        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 != NULL)
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
        if (prompt == NULL)
417
0
            return NULL;
418
0
        BUF_strlcpy(prompt, prompt1, len + 1);
419
0
        BUF_strlcat(prompt, object_desc, len + 1);
420
0
        if (object_name != NULL) {
421
0
            BUF_strlcat(prompt, prompt2, len + 1);
422
0
            BUF_strlcat(prompt, object_name, len + 1);
423
0
        }
424
0
        BUF_strlcat(prompt, prompt3, len + 1);
425
0
    }
426
0
    return prompt;
427
0
}
428
429
void *UI_add_user_data(UI *ui, void *user_data)
430
0
{
431
0
    void *old_data = ui->user_data;
432
0
    ui->user_data = user_data;
433
0
    return old_data;
434
0
}
435
436
void *UI_get0_user_data(UI *ui)
437
0
{
438
0
    return ui->user_data;
439
0
}
440
441
const char *UI_get0_result(UI *ui, int i)
442
0
{
443
0
    if (i < 0) {
444
0
        UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_SMALL);
445
0
        return NULL;
446
0
    }
447
0
    if (i >= sk_UI_STRING_num(ui->strings)) {
448
0
        UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_LARGE);
449
0
        return NULL;
450
0
    }
451
0
    return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
452
0
}
453
454
static int print_error(const char *str, size_t len, UI *ui)
455
0
{
456
0
    UI_STRING uis;
457
458
0
    memset(&uis, 0, sizeof(uis));
459
0
    uis.type = UIT_ERROR;
460
0
    uis.out_string = str;
461
462
0
    if (ui->meth->ui_write_string != NULL
463
0
        && ui->meth->ui_write_string(ui, &uis) <= 0)
464
0
        return -1;
465
0
    return 0;
466
0
}
467
468
int UI_process(UI *ui)
469
0
{
470
0
    int i, ok = 0;
471
472
0
    if (ui->meth->ui_open_session != NULL
473
0
        && ui->meth->ui_open_session(ui) <= 0) {
474
0
        ok = -1;
475
0
        goto err;
476
0
    }
477
478
0
    if (ui->flags & UI_FLAG_PRINT_ERRORS)
479
0
        ERR_print_errors_cb((int (*)(const char *, size_t, void *))
480
0
                            print_error, (void *)ui);
481
482
0
    for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
483
0
        if (ui->meth->ui_write_string != NULL
484
0
            && (ui->meth->ui_write_string(ui,
485
0
                                          sk_UI_STRING_value(ui->strings, i))
486
0
                <= 0))
487
0
        {
488
0
            ok = -1;
489
0
            goto err;
490
0
        }
491
0
    }
492
493
0
    if (ui->meth->ui_flush != NULL)
494
0
        switch (ui->meth->ui_flush(ui)) {
495
0
        case -1:               /* Interrupt/Cancel/something... */
496
0
            ok = -2;
497
0
            goto err;
498
0
        case 0:                /* Errors */
499
0
            ok = -1;
500
0
            goto err;
501
0
        default:               /* Success */
502
0
            ok = 0;
503
0
            break;
504
0
        }
505
506
0
    for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
507
0
        if (ui->meth->ui_read_string != NULL) {
508
0
            switch (ui->meth->ui_read_string(ui,
509
0
                                             sk_UI_STRING_value(ui->strings,
510
0
                                                                i))) {
511
0
            case -1:           /* Interrupt/Cancel/something... */
512
0
                ok = -2;
513
0
                goto err;
514
0
            case 0:            /* Errors */
515
0
                ok = -1;
516
0
                goto err;
517
0
            default:           /* Success */
518
0
                ok = 0;
519
0
                break;
520
0
            }
521
0
        }
522
0
    }
523
524
0
 err:
525
0
    if (ui->meth->ui_close_session != NULL
526
0
        && ui->meth->ui_close_session(ui) <= 0)
527
0
        return -1;
528
0
    return ok;
529
0
}
530
531
int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void))
532
0
{
533
0
    if (ui == NULL) {
534
0
        UIerr(UI_F_UI_CTRL, ERR_R_PASSED_NULL_PARAMETER);
535
0
        return -1;
536
0
    }
537
0
    switch (cmd) {
538
0
    case UI_CTRL_PRINT_ERRORS:
539
0
        {
540
0
            int save_flag = ! !(ui->flags & UI_FLAG_PRINT_ERRORS);
541
0
            if (i)
542
0
                ui->flags |= UI_FLAG_PRINT_ERRORS;
543
0
            else
544
0
                ui->flags &= ~UI_FLAG_PRINT_ERRORS;
545
0
            return save_flag;
546
0
        }
547
0
    case UI_CTRL_IS_REDOABLE:
548
0
        return ! !(ui->flags & UI_FLAG_REDOABLE);
549
0
    default:
550
0
        break;
551
0
    }
552
0
    UIerr(UI_F_UI_CTRL, UI_R_UNKNOWN_CONTROL_COMMAND);
553
0
    return -1;
554
0
}
555
556
int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
557
                        CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
558
0
{
559
0
    return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp,
560
0
                                   new_func, dup_func, free_func);
561
0
}
562
563
int UI_set_ex_data(UI *r, int idx, void *arg)
564
0
{
565
0
    return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
566
0
}
567
568
void *UI_get_ex_data(UI *r, int idx)
569
0
{
570
0
    return (CRYPTO_get_ex_data(&r->ex_data, idx));
571
0
}
572
573
void UI_set_default_method(const UI_METHOD *meth)
574
0
{
575
0
    default_UI_meth = meth;
576
0
}
577
578
const UI_METHOD *UI_get_default_method(void)
579
0
{
580
0
    if (default_UI_meth == NULL) {
581
0
        default_UI_meth = UI_OpenSSL();
582
0
    }
583
0
    return default_UI_meth;
584
0
}
585
586
const UI_METHOD *UI_get_method(UI *ui)
587
0
{
588
0
    return ui->meth;
589
0
}
590
591
const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth)
592
0
{
593
0
    ui->meth = meth;
594
0
    return ui->meth;
595
0
}
596
597
UI_METHOD *UI_create_method(char *name)
598
0
{
599
0
    UI_METHOD *ui_method = (UI_METHOD *)OPENSSL_malloc(sizeof(UI_METHOD));
600
601
0
    if (ui_method) {
602
0
        memset(ui_method, 0, sizeof(*ui_method));
603
0
        ui_method->name = BUF_strdup(name);
604
0
    }
605
0
    return ui_method;
606
0
}
607
608
/*
609
 * BIG FSCKING WARNING!!!! If you use this on a statically allocated method
610
 * (that is, it hasn't been allocated using UI_create_method(), you deserve
611
 * anything Murphy can throw at you and more! You have been warned.
612
 */
613
void UI_destroy_method(UI_METHOD *ui_method)
614
0
{
615
0
    OPENSSL_free(ui_method->name);
616
0
    ui_method->name = NULL;
617
0
    OPENSSL_free(ui_method);
618
0
}
619
620
int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui))
621
0
{
622
0
    if (method != NULL) {
623
0
        method->ui_open_session = opener;
624
0
        return 0;
625
0
    }
626
0
    return -1;
627
0
}
628
629
int UI_method_set_writer(UI_METHOD *method,
630
                         int (*writer) (UI *ui, UI_STRING *uis))
631
0
{
632
0
    if (method != NULL) {
633
0
        method->ui_write_string = writer;
634
0
        return 0;
635
0
    }
636
0
    return -1;
637
0
}
638
639
int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui))
640
0
{
641
0
    if (method != NULL) {
642
0
        method->ui_flush = flusher;
643
0
        return 0;
644
0
    }
645
0
    return -1;
646
0
}
647
648
int UI_method_set_reader(UI_METHOD *method,
649
                         int (*reader) (UI *ui, UI_STRING *uis))
650
0
{
651
0
    if (method != NULL) {
652
0
        method->ui_read_string = reader;
653
0
        return 0;
654
0
    }
655
0
    return -1;
656
0
}
657
658
int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui))
659
0
{
660
0
    if (method != NULL) {
661
0
        method->ui_close_session = closer;
662
0
        return 0;
663
0
    }
664
0
    return -1;
665
0
}
666
667
int UI_method_set_prompt_constructor(UI_METHOD *method,
668
                                     char *(*prompt_constructor) (UI *ui,
669
                                                                  const char
670
                                                                  *object_desc,
671
                                                                  const char
672
                                                                  *object_name))
673
0
{
674
0
    if (method != NULL) {
675
0
        method->ui_construct_prompt = prompt_constructor;
676
0
        return 0;
677
0
    }
678
0
    return -1;
679
0
}
680
681
int (*UI_method_get_opener(UI_METHOD *method)) (UI *)
682
0
{
683
0
    if (method != NULL)
684
0
        return method->ui_open_session;
685
0
    return NULL;
686
0
}
687
688
int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *)
689
0
{
690
0
    if (method != NULL)
691
0
        return method->ui_write_string;
692
0
    return NULL;
693
0
}
694
695
int (*UI_method_get_flusher(UI_METHOD *method)) (UI *)
696
0
{
697
0
    if (method != NULL)
698
0
        return method->ui_flush;
699
0
    return NULL;
700
0
}
701
702
int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *)
703
0
{
704
0
    if (method != NULL)
705
0
        return method->ui_read_string;
706
0
    return NULL;
707
0
}
708
709
int (*UI_method_get_closer(UI_METHOD *method)) (UI *)
710
0
{
711
0
    if (method != NULL)
712
0
        return method->ui_close_session;
713
0
    return NULL;
714
0
}
715
716
char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
717
                                                              const char *,
718
                                                              const char *)
719
0
{
720
0
    if (method != NULL)
721
0
        return method->ui_construct_prompt;
722
0
    return NULL;
723
0
}
724
725
enum UI_string_types UI_get_string_type(UI_STRING *uis)
726
0
{
727
0
    if (!uis)
728
0
        return UIT_NONE;
729
0
    return uis->type;
730
0
}
731
732
int UI_get_input_flags(UI_STRING *uis)
733
0
{
734
0
    if (!uis)
735
0
        return 0;
736
0
    return uis->input_flags;
737
0
}
738
739
const char *UI_get0_output_string(UI_STRING *uis)
740
0
{
741
0
    if (!uis)
742
0
        return NULL;
743
0
    return uis->out_string;
744
0
}
745
746
const char *UI_get0_action_string(UI_STRING *uis)
747
0
{
748
0
    if (!uis)
749
0
        return NULL;
750
0
    switch (uis->type) {
751
0
    case UIT_BOOLEAN:
752
0
        return uis->_.boolean_data.action_desc;
753
0
    default:
754
0
        return NULL;
755
0
    }
756
0
}
757
758
const char *UI_get0_result_string(UI_STRING *uis)
759
0
{
760
0
    if (!uis)
761
0
        return NULL;
762
0
    switch (uis->type) {
763
0
    case UIT_PROMPT:
764
0
    case UIT_VERIFY:
765
0
        return uis->result_buf;
766
0
    default:
767
0
        return NULL;
768
0
    }
769
0
}
770
771
const char *UI_get0_test_string(UI_STRING *uis)
772
0
{
773
0
    if (!uis)
774
0
        return NULL;
775
0
    switch (uis->type) {
776
0
    case UIT_VERIFY:
777
0
        return uis->_.string_data.test_buf;
778
0
    default:
779
0
        return NULL;
780
0
    }
781
0
}
782
783
int UI_get_result_minsize(UI_STRING *uis)
784
0
{
785
0
    if (!uis)
786
0
        return -1;
787
0
    switch (uis->type) {
788
0
    case UIT_PROMPT:
789
0
    case UIT_VERIFY:
790
0
        return uis->_.string_data.result_minsize;
791
0
    default:
792
0
        return -1;
793
0
    }
794
0
}
795
796
int UI_get_result_maxsize(UI_STRING *uis)
797
0
{
798
0
    if (!uis)
799
0
        return -1;
800
0
    switch (uis->type) {
801
0
    case UIT_PROMPT:
802
0
    case UIT_VERIFY:
803
0
        return uis->_.string_data.result_maxsize;
804
0
    default:
805
0
        return -1;
806
0
    }
807
0
}
808
809
int UI_set_result(UI *ui, UI_STRING *uis, const char *result)
810
0
{
811
0
    int l = strlen(result);
812
813
0
    ui->flags &= ~UI_FLAG_REDOABLE;
814
815
0
    if (!uis)
816
0
        return -1;
817
0
    switch (uis->type) {
818
0
    case UIT_PROMPT:
819
0
    case UIT_VERIFY:
820
0
        {
821
0
            char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize) + 1];
822
0
            char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize) + 1];
823
824
0
            BIO_snprintf(number1, sizeof(number1), "%d",
825
0
                         uis->_.string_data.result_minsize);
826
0
            BIO_snprintf(number2, sizeof(number2), "%d",
827
0
                         uis->_.string_data.result_maxsize);
828
829
0
            if (l < uis->_.string_data.result_minsize) {
830
0
                ui->flags |= UI_FLAG_REDOABLE;
831
0
                UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_SMALL);
832
0
                ERR_add_error_data(5, "You must type in ",
833
0
                                   number1, " to ", number2, " characters");
834
0
                return -1;
835
0
            }
836
0
            if (l > uis->_.string_data.result_maxsize) {
837
0
                ui->flags |= UI_FLAG_REDOABLE;
838
0
                UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_LARGE);
839
0
                ERR_add_error_data(5, "You must type in ",
840
0
                                   number1, " to ", number2, " characters");
841
0
                return -1;
842
0
            }
843
0
        }
844
845
0
        if (!uis->result_buf) {
846
0
            UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
847
0
            return -1;
848
0
        }
849
850
0
        BUF_strlcpy(uis->result_buf, result,
851
0
                    uis->_.string_data.result_maxsize + 1);
852
0
        break;
853
0
    case UIT_BOOLEAN:
854
0
        {
855
0
            const char *p;
856
857
0
            if (!uis->result_buf) {
858
0
                UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
859
0
                return -1;
860
0
            }
861
862
0
            uis->result_buf[0] = '\0';
863
0
            for (p = result; *p; p++) {
864
0
                if (strchr(uis->_.boolean_data.ok_chars, *p)) {
865
0
                    uis->result_buf[0] = uis->_.boolean_data.ok_chars[0];
866
0
                    break;
867
0
                }
868
0
                if (strchr(uis->_.boolean_data.cancel_chars, *p)) {
869
0
                    uis->result_buf[0] = uis->_.boolean_data.cancel_chars[0];
870
0
                    break;
871
0
                }
872
0
            }
873
0
        }
874
0
    default:
875
0
        break;
876
0
    }
877
0
    return 0;
878
0
}