int setup_ui_method(void) { 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; }
int set_android_ui(void) { UI_METHOD *ui_method = UI_create_method("AnyConnect Android VPN UI"); UI_method_set_opener(ui_method, ui_android_open); UI_method_set_reader(ui_method, ui_android_read); UI_method_set_writer(ui_method, ui_android_write); UI_method_set_closer(ui_method, ui_android_close); UI_set_default_method(ui_method); return 0; }
int main(void) { char buffer1[64], buffer2[64]; UI_METHOD *ui_method; UI *ui; printf("Testing UI_UTIL_read_pw:\n"); if (UI_UTIL_read_pw(&buffer1[0], &buffer2[0], sizeof(buffer1) - 1, "Prompt", 1) == 0) printf("Password: \"%s\"\n", &buffer1[0]); else printf("Error getting password\n"); printf("Testing UI with default UI method:\n"); if((ui = UI_new()) != NULL) { TestUI(ui); UI_free(ui); } else printf("Couldn't setup method\n"); printf("Testing UI with UI method with wrappers:\n"); if((ui_method = UI_create_method((char *)"Test method")) != NULL) { if((ui = UI_new_method(ui_method)) != NULL) { 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); TestUI(ui); UI_free(ui); } else printf("Couldn't setup method\n"); UI_destroy_method(ui_method); } else printf("Couldn't create method\n"); return(0); }
static UI_METHOD *create_openssl_ui(struct openconnect_info *vpninfo) { UI_METHOD *ui_method = UI_create_method((char *)"AnyConnect VPN UI"); /* There is a race condition here because of the use of the static ui_vpninfo pointer. This sucks, but it's OpenSSL's fault and in practice it's *never* going to hurt us. This UI is only used for loading certificates from a TPM; for PKCS#12 and PEM files we hook the passphrase request differently. The ui_vpninfo variable is set here, and is used from ui_open() when the TPM ENGINE decides it needs to ask the user for a PIN. The race condition exists because theoretically, there could be more than one thread using libopenconnect and trying to authenticate to a VPN server, within the *same* process. And if *both* are using certificates from the TPM, and *both* manage to be within that short window of time between setting ui_vpninfo and invoking ui_open() to fetch the PIN, then one connection's ->process_auth_form() could get a PIN request for the *other* connection. However, the only thing that ever does run libopenconnect more than once from the same process is KDE's NetworkManager support, and NetworkManager doesn't *support* having more than one VPN connected anyway, so first that would have to be fixed and then you'd have to connect to two VPNs simultaneously by clicking 'connect' on both at *exactly* the same time and then getting *really* unlucky. Oh, and the KDE support won't be using OpenSSL anyway because of licensing conflicts... so although this sucks, I'm not going to lose sleep over it. */ ui_vpninfo = vpninfo; /* Set up a UI method of our own for password/passphrase requests */ UI_method_set_opener(ui_method, ui_open); UI_method_set_writer(ui_method, ui_write); UI_method_set_flusher(ui_method, ui_flush); UI_method_set_closer(ui_method, ui_close); return ui_method; }
UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag) { struct pem_password_cb_data *data = NULL; UI_METHOD *ui_method = NULL; if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL || (ui_method = UI_create_method("PEM password callback wrapper")) == NULL || UI_method_set_opener(ui_method, ui_open) < 0 || UI_method_set_reader(ui_method, ui_read) < 0 || UI_method_set_writer(ui_method, ui_write) < 0 || UI_method_set_closer(ui_method, ui_close) < 0 || !RUN_ONCE(&get_index_once, ui_method_data_index_init) || UI_method_set_ex_data(ui_method, ui_method_data_index, data) < 0) { UI_destroy_method(ui_method); OPENSSL_free(data); return NULL; } data->rwflag = rwflag; data->cb = cb; return ui_method; }