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