mirror of https://github.com/openssl/openssl.git
				
				
				
			
		
			
	
	
		
			198 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
		
		
			
		
	
	
			198 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
|  | /*
 | ||
|  |  * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. | ||
|  |  * | ||
|  |  * Licensed under the OpenSSL license (the "License").  You may not use | ||
|  |  * this file except in compliance with the License.  You can obtain a copy | ||
|  |  * in the file LICENSE in the source distribution or at | ||
|  |  * https://www.openssl.org/source/license.html
 | ||
|  |  */ | ||
|  | 
 | ||
|  | #include <string.h>
 | ||
|  | #include <openssl/err.h>
 | ||
|  | #include <openssl/ui.h>
 | ||
|  | #include "apps_ui.h"
 | ||
|  | 
 | ||
|  | static UI_METHOD *ui_method = NULL; | ||
|  | static const UI_METHOD *ui_fallback_method = NULL; | ||
|  | 
 | ||
|  | 
 | ||
|  | static int ui_open(UI *ui) | ||
|  | { | ||
|  |     int (*opener)(UI *ui) = UI_method_get_opener(ui_fallback_method); | ||
|  | 
 | ||
|  |     if (opener) | ||
|  |         return opener(ui); | ||
|  |     return 1; | ||
|  | } | ||
|  | 
 | ||
|  | static int ui_read(UI *ui, UI_STRING *uis) | ||
|  | { | ||
|  |     int (*reader)(UI *ui, UI_STRING *uis) = NULL; | ||
|  | 
 | ||
|  |     if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD | ||
|  |         && UI_get0_user_data(ui)) { | ||
|  |         switch (UI_get_string_type(uis)) { | ||
|  |         case UIT_PROMPT: | ||
|  |         case UIT_VERIFY: | ||
|  |             { | ||
|  |                 const char *password = | ||
|  |                     ((PW_CB_DATA *)UI_get0_user_data(ui))->password; | ||
|  |                 if (password && password[0] != '\0') { | ||
|  |                     UI_set_result(ui, uis, password); | ||
|  |                     return 1; | ||
|  |                 } | ||
|  |             } | ||
|  |             break; | ||
|  |         case UIT_NONE: | ||
|  |         case UIT_BOOLEAN: | ||
|  |         case UIT_INFO: | ||
|  |         case UIT_ERROR: | ||
|  |             break; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     reader = UI_method_get_reader(ui_fallback_method); | ||
|  |     if (reader) | ||
|  |         return reader(ui, uis); | ||
|  |     return 1; | ||
|  | } | ||
|  | 
 | ||
|  | static int ui_write(UI *ui, UI_STRING *uis) | ||
|  | { | ||
|  |     int (*writer)(UI *ui, UI_STRING *uis) = NULL; | ||
|  | 
 | ||
|  |     if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD | ||
|  |         && UI_get0_user_data(ui)) { | ||
|  |         switch (UI_get_string_type(uis)) { | ||
|  |         case UIT_PROMPT: | ||
|  |         case UIT_VERIFY: | ||
|  |             { | ||
|  |                 const char *password = | ||
|  |                     ((PW_CB_DATA *)UI_get0_user_data(ui))->password; | ||
|  |                 if (password && password[0] != '\0') | ||
|  |                     return 1; | ||
|  |             } | ||
|  |             break; | ||
|  |         case UIT_NONE: | ||
|  |         case UIT_BOOLEAN: | ||
|  |         case UIT_INFO: | ||
|  |         case UIT_ERROR: | ||
|  |             break; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     writer = UI_method_get_writer(ui_fallback_method); | ||
|  |     if (writer) | ||
|  |         return writer(ui, uis); | ||
|  |     return 1; | ||
|  | } | ||
|  | 
 | ||
|  | static int ui_close(UI *ui) | ||
|  | { | ||
|  |     int (*closer)(UI *ui) = UI_method_get_closer(ui_fallback_method); | ||
|  | 
 | ||
|  |     if (closer) | ||
|  |         return closer(ui); | ||
|  |     return 1; | ||
|  | } | ||
|  | 
 | ||
|  | int setup_ui_method(void) | ||
|  | { | ||
|  |     ui_fallback_method = UI_null(); | ||
|  | #ifndef OPENSSL_NO_UI_CONSOLE
 | ||
|  |     ui_fallback_method = UI_OpenSSL(); | ||
|  | #endif
 | ||
|  |     ui_method = UI_create_method("OpenSSL application user interface"); | ||
|  |     UI_method_set_opener(ui_method, ui_open); | ||
|  |     UI_method_set_reader(ui_method, ui_read); | ||
|  |     UI_method_set_writer(ui_method, ui_write); | ||
|  |     UI_method_set_closer(ui_method, ui_close); | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | void destroy_ui_method(void) | ||
|  | { | ||
|  |     if (ui_method) { | ||
|  |         UI_destroy_method(ui_method); | ||
|  |         ui_method = NULL; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | const UI_METHOD *get_ui_method(void) | ||
|  | { | ||
|  |     return ui_method; | ||
|  | } | ||
|  | 
 | ||
|  | static void *ui_malloc(int sz, const char *what) | ||
|  | { | ||
|  |     void *vp = OPENSSL_malloc(sz); | ||
|  | 
 | ||
|  |     if (vp == NULL) { | ||
|  |         BIO_printf(bio_err, "Could not allocate %d bytes for %s\n", sz, what); | ||
|  |         ERR_print_errors(bio_err); | ||
|  |         exit(1); | ||
|  |     } | ||
|  |     return vp; | ||
|  | } | ||
|  | 
 | ||
|  | int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data) | ||
|  | { | ||
|  |     int res = 0; | ||
|  |     UI *ui; | ||
|  |     int ok = 0; | ||
|  |     char *buff = NULL; | ||
|  |     int ui_flags = 0; | ||
|  |     const char *prompt_info = NULL; | ||
|  |     char *prompt; | ||
|  | 
 | ||
|  |     if ((ui = UI_new_method(ui_method)) == NULL) | ||
|  |         return 0; | ||
|  | 
 | ||
|  |     if (cb_data != NULL && cb_data->prompt_info != NULL) | ||
|  |         prompt_info = cb_data->prompt_info; | ||
|  |     prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); | ||
|  |     if (prompt == NULL) { | ||
|  |         BIO_printf(bio_err, "Out of memory\n"); | ||
|  |         UI_free(ui); | ||
|  |         return 0; | ||
|  |     } | ||
|  | 
 | ||
|  |     ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; | ||
|  |     UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); | ||
|  | 
 | ||
|  |     /* We know that there is no previous user data to return to us */ | ||
|  |     (void)UI_add_user_data(ui, cb_data); | ||
|  | 
 | ||
|  |     ok = UI_add_input_string(ui, prompt, ui_flags, buf, | ||
|  |                              PW_MIN_LENGTH, bufsiz - 1); | ||
|  | 
 | ||
|  |     if (ok >= 0 && verify) { | ||
|  |         buff = ui_malloc(bufsiz, "password buffer"); | ||
|  |         ok = UI_add_verify_string(ui, prompt, ui_flags, buff, | ||
|  |                                   PW_MIN_LENGTH, bufsiz - 1, buf); | ||
|  |     } | ||
|  |     if (ok >= 0) | ||
|  |         do { | ||
|  |             ok = UI_process(ui); | ||
|  |         } while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); | ||
|  | 
 | ||
|  |     OPENSSL_clear_free(buff, (unsigned int)bufsiz); | ||
|  | 
 | ||
|  |     if (ok >= 0) | ||
|  |         res = strlen(buf); | ||
|  |     if (ok == -1) { | ||
|  |         BIO_printf(bio_err, "User interface error\n"); | ||
|  |         ERR_print_errors(bio_err); | ||
|  |         OPENSSL_cleanse(buf, (unsigned int)bufsiz); | ||
|  |         res = 0; | ||
|  |     } | ||
|  |     if (ok == -2) { | ||
|  |         BIO_printf(bio_err, "aborted!\n"); | ||
|  |         OPENSSL_cleanse(buf, (unsigned int)bufsiz); | ||
|  |         res = 0; | ||
|  |     } | ||
|  |     UI_free(ui); | ||
|  |     OPENSSL_free(prompt); | ||
|  |     return res; | ||
|  | } |