1 /* $OpenBSD: ui.h,v 1.12 2020/09/24 19:20:32 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 module libressl_d.openssl.ui;
59 
60 
61 private static import core.stdc.config;
62 private static import libressl_d.openssl.stack;
63 public import libressl_d.openssl.crypto;
64 public import libressl_d.openssl.opensslconf;
65 public import libressl_d.openssl.ossl_typ;
66 public import libressl_d.openssl.safestack;
67 
68 version (OPENSSL_NO_DEPRECATED) {
69 } else {
70 	public import libressl_d.openssl.crypto;
71 }
72 
73 extern (C):
74 nothrow @nogc:
75 
76 /* Declared already in ossl_typ.h */
77 /* alias UI = ui_st; */
78 /* alias UI_METHOD = ui_method_st; */
79 
80 /*
81  * All the following functions return -1 or NULL on error and in some cases
82  * (UI_process()) -2 if interrupted or in some other way cancelled.
83  * When everything is fine, they return 0, a positive value or a non-NULL
84  * pointer, all depending on their purpose.
85  */
86 
87 /* Creators and destructor.   */
88 libressl_d.openssl.ossl_typ.UI* UI_new();
89 libressl_d.openssl.ossl_typ.UI* UI_new_method(const (libressl_d.openssl.ossl_typ.UI_METHOD)* method);
90 void UI_free(libressl_d.openssl.ossl_typ.UI* ui);
91 
92 /*
93  * The following functions are used to add strings to be printed and prompt
94  * strings to prompt for data.  The names are UI_{add,dup}_<function>_string
95  * and UI_{add,dup}_input_boolean.
96  *
97  * UI_{add,dup}_<function>_string have the following meanings:
98  *	add	add a text or prompt string.  The pointers given to these
99  *		functions are used verbatim, no copying is done.
100  *	dup	make a copy of the text or prompt string, then add the copy
101  *		to the collection of strings in the user interface.
102  *	<function>
103  *		The function is a name for the functionality that the given
104  *		string shall be used for.  It can be one of:
105  *			input	use the string as data prompt.
106  *			verify	use the string as verification prompt.  This
107  *				is used to verify a previous input.
108  *			info	use the string for informational output.
109  *			error	use the string for error output.
110  * Honestly, there's currently no difference between info and error for the
111  * moment.
112  *
113  * UI_{add,dup}_input_boolean have the same semantics for "add" and "dup",
114  * and are typically used when one wants to prompt for a yes/no response.
115  *
116  * All of the functions in this group take a UI and a prompt string.
117  * The string input and verify addition functions also take a flag argument,
118  * a buffer for the result to end up in, a minimum input size and a maximum
119  * input size (the result buffer MUST be large enough to be able to contain
120  * the maximum number of characters).  Additionally, the verify addition
121  * functions takes another buffer to compare the result against.
122  * The boolean input functions take an action description string (which should
123  * be safe to ignore if the expected user action is obvious, for example with
124  * a dialog box with an OK button and a Cancel button), a string of acceptable
125  * characters to mean OK and to mean Cancel.  The two last strings are checked
126  * to make sure they don't have common characters.  Additionally, the same
127  * flag argument as for the string input is taken, as well as a result buffer.
128  * The result buffer is required to be at least one byte long.  Depending on
129  * the answer, the first character from the OK or the Cancel character strings
130  * will be stored in the first byte of the result buffer.  No NUL will be
131  * added, so the result is *not* a string.
132  *
133  * On success, the functions all return an index of the added information.
134  * That index is useful when retrieving results with UI_get0_result().
135  */
136 int UI_add_input_string(libressl_d.openssl.ossl_typ.UI* ui, const (char)* prompt, int flags, char* result_buf, int minsize, int maxsize);
137 int UI_dup_input_string(libressl_d.openssl.ossl_typ.UI* ui, const (char)* prompt, int flags, char* result_buf, int minsize, int maxsize);
138 int UI_add_verify_string(libressl_d.openssl.ossl_typ.UI* ui, const (char)* prompt, int flags, char* result_buf, int minsize, int maxsize, const (char)* test_buf);
139 int UI_dup_verify_string(libressl_d.openssl.ossl_typ.UI* ui, const (char)* prompt, int flags, char* result_buf, int minsize, int maxsize, const (char)* test_buf);
140 int UI_add_input_boolean(libressl_d.openssl.ossl_typ.UI* ui, const (char)* prompt, const (char)* action_desc, const (char)* ok_chars, const (char)* cancel_chars, int flags, char* result_buf);
141 int UI_dup_input_boolean(libressl_d.openssl.ossl_typ.UI* ui, const (char)* prompt, const (char)* action_desc, const (char)* ok_chars, const (char)* cancel_chars, int flags, char* result_buf);
142 int UI_add_info_string(libressl_d.openssl.ossl_typ.UI* ui, const (char)* text);
143 int UI_dup_info_string(libressl_d.openssl.ossl_typ.UI* ui, const (char)* text);
144 int UI_add_error_string(libressl_d.openssl.ossl_typ.UI* ui, const (char)* text);
145 int UI_dup_error_string(libressl_d.openssl.ossl_typ.UI* ui, const (char)* text);
146 
147 /* These are the possible flags.  They can be or'ed together. */
148 /**
149  * Use to have echoing of input
150  */
151 enum UI_INPUT_FLAG_ECHO = 0x01;
152 
153 /**
154  * Use a default password.  Where that password is found is completely
155  * up to the application, it might for example be in the user data set
156  * with UI_add_user_data().  It is not recommended to have more than
157  * one input in each UI being marked with this flag, or the application
158  * might get confused.
159  */
160 enum UI_INPUT_FLAG_DEFAULT_PWD = 0x02;
161 
162 /**
163  * Users of these routines may want to define flags of their own.  The core
164  * UI won't look at those, but will pass them on to the method routines.  They
165  * must use higher bits so they don't get confused with the UI bits above.
166  * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use.  A good
167  * example of use is this:
168  *
169  *	#define MY_UI_FLAG1	(0x01 << UI_INPUT_FLAG_USER_BASE)
170  */
171 enum UI_INPUT_FLAG_USER_BASE = 16;
172 
173 /**
174  * The following function helps construct a prompt.  object_desc is a
175  * textual short description of the object, for example "pass phrase",
176  * and object_name is the name of the object \(might be a card name or
177  * a file name.
178  * The returned string shall always be allocated on the heap with
179  * malloc(), and need to be free'd with free().
180  *
181  * If the ui_method doesn't contain a pointer to a user-defined prompt
182  * constructor, a default string is built, looking like this:
183  *
184  *	"Enter {object_desc} for {object_name}:"
185  *
186  * So, if object_desc has the value "pass phrase" and object_name has
187  * the value "foo.key", the resulting string is:
188  *
189  *	"Enter pass phrase for foo.key:"
190  */
191 char* UI_construct_prompt(libressl_d.openssl.ossl_typ.UI* ui_method, const (char)* object_desc, const (char)* object_name);
192 
193 /**
194  * The following function is used to store a pointer to user-specific data.
195  * Any previous such pointer will be returned and replaced.
196  *
197  * For callback purposes, this function makes a lot more sense than using
198  * ex_data, since the latter requires that different parts of OpenSSL or
199  * applications share the same ex_data index.
200  *
201  * Note that the UI_OpenSSL() method completely ignores the user data.
202  * Other methods may not, however.
203  */
204 void* UI_add_user_data(libressl_d.openssl.ossl_typ.UI* ui, void* user_data);
205 
206 /**
207  * We need a user data retrieving function as well.
208  */
209 void* UI_get0_user_data(libressl_d.openssl.ossl_typ.UI* ui);
210 
211 /**
212  * Return the result associated with a prompt given with the index i.
213  */
214 const (char)* UI_get0_result(libressl_d.openssl.ossl_typ.UI* ui, int i);
215 
216 /**
217  * When all strings have been added, process the whole thing.
218  */
219 int UI_process(libressl_d.openssl.ossl_typ.UI* ui);
220 
221 /**
222  * Give a user interface parametrised control commands.  This can be used to
223  * send down an integer, a data pointer or a function pointer, as well as
224  * be used to get information from a UI.
225  */
226 int UI_ctrl(libressl_d.openssl.ossl_typ.UI* ui, int cmd, core.stdc.config.c_long i, void* p, void function() f);
227 
228 /* The commands */
229 /**
230  * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the
231  * OpenSSL error stack before printing any info or added error messages and
232  * before any prompting.
233  */
234 enum UI_CTRL_PRINT_ERRORS = 1;
235 
236 /**
237  * Check if a UI_process() is possible to do again with the same instance of
238  * a user interface.  This makes UI_ctrl() return 1 if it is redoable, and 0
239  * if not.
240  */
241 enum UI_CTRL_IS_REDOABLE = 2;
242 
243 /* Some methods may use extra data */
244 pragma(inline, true)
245 int UI_set_app_data(libressl_d.openssl.ossl_typ.UI* s, void* arg)
246 
247 	do
248 	{
249 		return .UI_set_ex_data(s, 0, arg);
250 	}
251 
252 pragma(inline, true)
253 void* UI_get_app_data(libressl_d.openssl.ossl_typ.UI* s)
254 
255 	do
256 	{
257 		return .UI_get_ex_data(s, 0);
258 	}
259 
260 int UI_get_ex_new_index(core.stdc.config.c_long argl, void* argp, libressl_d.openssl.ossl_typ.CRYPTO_EX_new* new_func, libressl_d.openssl.ossl_typ.CRYPTO_EX_dup* dup_func, libressl_d.openssl.ossl_typ.CRYPTO_EX_free* free_func);
261 int UI_set_ex_data(libressl_d.openssl.ossl_typ.UI* r, int idx, void* arg);
262 void* UI_get_ex_data(libressl_d.openssl.ossl_typ.UI* r, int idx);
263 
264 /* Use specific methods instead of the built-in one */
265 void UI_set_default_method(const (libressl_d.openssl.ossl_typ.UI_METHOD)* meth);
266 const (libressl_d.openssl.ossl_typ.UI_METHOD)* UI_get_default_method();
267 const (libressl_d.openssl.ossl_typ.UI_METHOD)* UI_get_method(libressl_d.openssl.ossl_typ.UI* ui);
268 const (libressl_d.openssl.ossl_typ.UI_METHOD)* UI_set_method(libressl_d.openssl.ossl_typ.UI* ui, const (libressl_d.openssl.ossl_typ.UI_METHOD)* meth);
269 
270 /**
271  * The method with all the built-in thingies
272  */
273 libressl_d.openssl.ossl_typ.UI_METHOD* UI_OpenSSL();
274 
275 /*
276  * ---------- For method writers ----------
277  * A method contains a number of functions that implement the low level
278  * of the User Interface.  The functions are:
279  *
280  *	an opener	This function starts a session, maybe by opening
281  *			a channel to a tty, or by opening a window.
282  *	a writer	This function is called to write a given string,
283  *			maybe to the tty, maybe as a field label in a
284  *			window.
285  *	a flusher	This function is called to flush everything that
286  *			has been output so far.  It can be used to actually
287  *			display a dialog box after it has been built.
288  *	a reader	This function is called to read a given prompt,
289  *			maybe from the tty, maybe from a field in a
290  *			window.  Note that it's called wth all string
291  *			structures, not only the prompt ones, so it must
292  *			check such things itself.
293  *	a closer	This function closes the session, maybe by closing
294  *			the channel to the tty, or closing the window.
295  *
296  * All these functions are expected to return:
297  *
298  *	 0	on error.
299  *	 1	on success.
300  *	-1	on out-of-band events, for example if some prompting has
301  *		been canceled (by pressing Ctrl-C, for example).  This is
302  *		only checked when returned by the flusher or the reader.
303  *
304  * The way this is used, the opener is first called, then the writer for all
305  * strings, then the flusher, then the reader for all strings and finally the
306  * closer.  Note that if you want to prompt from a terminal or other command
307  * line interface, the best is to have the reader also write the prompts
308  * instead of having the writer do it.  If you want to prompt from a dialog
309  * box, the writer can be used to build up the contents of the box, and the
310  * flusher to actually display the box and run the event loop until all data
311  * has been given, after which the reader only grabs the given data and puts
312  * them back into the UI strings.
313  *
314  * All method functions take a UI as argument.  Additionally, the writer and
315  * the reader take a UI_STRING.
316  */
317 
318 /*
319  * The UI_STRING type is the data structure that contains all the needed info
320  * about a string or a prompt, including test data for a verification prompt.
321  */
322 struct ui_string_st;
323 alias UI_STRING = .ui_string_st;
324 
325 //DECLARE_STACK_OF(UI_STRING)
326 struct stack_st_UI_STRING
327 {
328 	libressl_d.openssl.stack._STACK stack;
329 }
330 
331 /**
332  * The different types of strings that are currently supported.
333  * This is only needed by method authors.
334  */
335 enum UI_string_types
336 {
337 	UIT_NONE = 0,
338 
339 	/**
340 	 * Prompt for a string
341 	 */
342 	UIT_PROMPT,
343 
344 	/**
345 	 * Prompt for a string and verify
346 	 */
347 	UIT_VERIFY,
348 
349 	/**
350 	 * Prompt for a yes/no response
351 	 */
352 	UIT_BOOLEAN,
353 
354 	/**
355 	 * Send info to the user
356 	 */
357 	UIT_INFO,
358 
359 	/**
360 	 * Send an error message to the user
361 	 */
362 	UIT_ERROR,
363 }
364 
365 //Declaration name in C language
366 enum
367 {
368 	UIT_NONE = .UI_string_types.UIT_NONE,
369 	UIT_PROMPT = .UI_string_types.UIT_PROMPT,
370 	UIT_VERIFY = .UI_string_types.UIT_VERIFY,
371 	UIT_BOOLEAN = .UI_string_types.UIT_BOOLEAN,
372 	UIT_INFO = .UI_string_types.UIT_INFO,
373 	UIT_ERROR = .UI_string_types.UIT_ERROR,
374 }
375 
376 /* Create and manipulate methods */
377 libressl_d.openssl.ossl_typ.UI_METHOD* UI_create_method(const (char)* name);
378 void UI_destroy_method(libressl_d.openssl.ossl_typ.UI_METHOD* ui_method);
379 int UI_method_set_opener(libressl_d.openssl.ossl_typ.UI_METHOD* method, int function(libressl_d.openssl.ossl_typ.UI* ui) opener);
380 int UI_method_set_writer(libressl_d.openssl.ossl_typ.UI_METHOD* method, int function(libressl_d.openssl.ossl_typ.UI* ui, .UI_STRING* uis) writer);
381 int UI_method_set_flusher(libressl_d.openssl.ossl_typ.UI_METHOD* method, int function(libressl_d.openssl.ossl_typ.UI* ui) flusher);
382 int UI_method_set_reader(libressl_d.openssl.ossl_typ.UI_METHOD* method, int function(libressl_d.openssl.ossl_typ.UI* ui, .UI_STRING* uis) reader);
383 int UI_method_set_closer(libressl_d.openssl.ossl_typ.UI_METHOD* method, int function(libressl_d.openssl.ossl_typ.UI* ui) closer);
384 int UI_method_set_prompt_constructor(libressl_d.openssl.ossl_typ.UI_METHOD* method, char* function(libressl_d.openssl.ossl_typ.UI* ui, const (char)* object_desc, const (char)* object_name) prompt_constructor);
385 //int (*UI_method_get_opener(const (libressl_d.openssl.ossl_typ.UI_METHOD)* method))(libressl_d.openssl.ossl_typ.UI*);
386 //int (*UI_method_get_writer(const (libressl_d.openssl.ossl_typ.UI_METHOD)* method))(libressl_d.openssl.ossl_typ.UI*, .UI_STRING*);
387 //int (*UI_method_get_flusher(const (libressl_d.openssl.ossl_typ.UI_METHOD)* method))(libressl_d.openssl.ossl_typ.UI*);
388 //int (*UI_method_get_reader(const (libressl_d.openssl.ossl_typ.UI_METHOD)* method))(libressl_d.openssl.ossl_typ.UI*, .UI_STRING*);
389 //int (*UI_method_get_closer(const (libressl_d.openssl.ossl_typ.UI_METHOD)* method))(libressl_d.openssl.ossl_typ.UI*);
390 //char* (*UI_method_get_prompt_constructor(const (libressl_d.openssl.ossl_typ.UI_METHOD)* method))(libressl_d.openssl.ossl_typ.UI*, const (char)*, const (char)*);
391 
392 /*
393  * The following functions are helpers for method writers to access relevant
394  * data from a UI_STRING.
395  */
396 
397 /**
398  * Return type of the UI_STRING
399  */
400 enum .UI_string_types UI_get_string_type(.UI_STRING* uis);
401 
402 /**
403  * Return input flags of the UI_STRING
404  */
405 int UI_get_input_flags(.UI_STRING* uis);
406 
407 /**
408  * Return the actual string to output (the prompt, info or error)
409  */
410 const (char)* UI_get0_output_string(.UI_STRING* uis);
411 
412 /**
413  * Return the optional action string to output (boolean prompt instruction)
414  */
415 const (char)* UI_get0_action_string(.UI_STRING* uis);
416 
417 /**
418  * Return the result of a prompt
419  */
420 const (char)* UI_get0_result_string(.UI_STRING* uis);
421 
422 /**
423  * Return the string to test the result against.  Only useful with verifies.
424  */
425 const (char)* UI_get0_test_string(.UI_STRING* uis);
426 
427 /**
428  * Return the required minimum size of the result
429  */
430 int UI_get_result_minsize(.UI_STRING* uis);
431 
432 /**
433  * Return the required maximum size of the result
434  */
435 int UI_get_result_maxsize(.UI_STRING* uis);
436 
437 /**
438  * Set the result of a UI_STRING.
439  */
440 int UI_set_result(libressl_d.openssl.ossl_typ.UI* ui, .UI_STRING* uis, const (char)* result);
441 
442 /* A couple of popular utility functions */
443 int UI_UTIL_read_pw_string(char* buf, int length_, const (char)* prompt, int verify);
444 int UI_UTIL_read_pw(char* buf, char* buff, int size, const (char)* prompt, int verify);
445 
446 /* BEGIN ERROR CODES */
447 /*
448  * The following lines are auto generated by the script mkerr.pl. Any changes
449  * made after this point may be overwritten when the script is next run.
450  */
451 void ERR_load_UI_strings();
452 
453 /* Error codes for the UI functions. */
454 
455 /* Function codes. */
456 enum UI_F_GENERAL_ALLOCATE_BOOLEAN = 108;
457 enum UI_F_GENERAL_ALLOCATE_PROMPT = 109;
458 enum UI_F_GENERAL_ALLOCATE_STRING = 100;
459 enum UI_F_UI_CTRL = 111;
460 enum UI_F_UI_DUP_ERROR_STRING = 101;
461 enum UI_F_UI_DUP_INFO_STRING = 102;
462 enum UI_F_UI_DUP_INPUT_BOOLEAN = 110;
463 enum UI_F_UI_DUP_INPUT_STRING = 103;
464 enum UI_F_UI_DUP_VERIFY_STRING = 106;
465 enum UI_F_UI_GET0_RESULT = 107;
466 enum UI_F_UI_NEW_METHOD = 104;
467 enum UI_F_UI_SET_RESULT = 105;
468 
469 /* Reason codes. */
470 enum UI_R_COMMON_OK_AND_CANCEL_CHARACTERS = 104;
471 enum UI_R_INDEX_TOO_LARGE = 102;
472 enum UI_R_INDEX_TOO_SMALL = 103;
473 enum UI_R_NO_RESULT_BUFFER = 105;
474 enum UI_R_RESULT_TOO_LARGE = 100;
475 enum UI_R_RESULT_TOO_SMALL = 101;
476 enum UI_R_UNKNOWN_CONTROL_COMMAND = 106;