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