static PKCS11H_BOOL _pkcs11_openvpn_show_pkcs11_ids_pin_prompt( void *const global_data, void *const user_data, const pkcs11h_token_id_t token, const unsigned retry, char *const pin, const size_t pin_max ) { struct gc_arena gc = gc_new(); struct buffer pass_prompt = alloc_buf_gc(128, &gc); (void)global_data; (void)user_data; (void)retry; ASSERT(token!=NULL); buf_printf(&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display); if (!query_user_SINGLE(BSTR(&pass_prompt), BLEN(&pass_prompt), pin, pin_max, false)) { msg(M_FATAL, "Could not retrieve the PIN"); } gc_free(&gc); if (!strcmp(pin, "cancel")) { return FALSE; } else { return TRUE; } }
bool get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix, const unsigned int flags, const char *auth_challenge) { struct gc_arena gc = gc_new(); if (!up->defined) { bool from_authfile = (auth_file && !streq(auth_file, "stdin")); bool username_from_stdin = false; bool password_from_stdin = false; bool response_from_stdin = true; if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED) { msg(M_WARN, "Note: previous '%s' credentials failed", prefix); } #ifdef ENABLE_MANAGEMENT /* * Get username/password from management interface? */ if (management && (!from_authfile && (flags & GET_USER_PASS_MANAGEMENT)) && management_query_user_pass_enabled(management)) { const char *sc = NULL; response_from_stdin = false; if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED) { management_auth_failure(management, prefix, "previous auth credentials failed"); } #ifdef ENABLE_CLIENT_CR if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE)) { sc = auth_challenge; } #endif if (!management_query_user_pass(management, up, prefix, flags, sc)) { if ((flags & GET_USER_PASS_NOFATAL) != 0) { return false; } else { msg(M_FATAL, "ERROR: could not read %s username/password/ok/string from management interface", prefix); } } } else #endif /* ifdef ENABLE_MANAGEMENT */ /* * Get NEED_OK confirmation from the console */ if (flags & GET_USER_PASS_NEED_OK) { struct buffer user_prompt = alloc_buf_gc(128, &gc); buf_printf(&user_prompt, "NEED-OK|%s|%s:", prefix, up->username); if (!query_user_SINGLE(BSTR(&user_prompt), BLEN(&user_prompt), up->password, USER_PASS_LEN, false)) { msg(M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix); } if (!strlen(up->password)) { strcpy(up->password, "ok"); } } else if (flags & GET_USER_PASS_INLINE_CREDS) { struct buffer buf; buf_set_read(&buf, (uint8_t *) auth_file, strlen(auth_file) + 1); if (!(flags & GET_USER_PASS_PASSWORD_ONLY)) { buf_parse(&buf, '\n', up->username, USER_PASS_LEN); } buf_parse(&buf, '\n', up->password, USER_PASS_LEN); } /* * Read from auth file unless this is a dynamic challenge request. */ else if (from_authfile && !(flags & GET_USER_PASS_DYNAMIC_CHALLENGE)) { /* * Try to get username/password from a file. */ FILE *fp; char password_buf[USER_PASS_LEN] = { '\0' }; fp = platform_fopen(auth_file, "r"); if (!fp) { msg(M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file); } if ((flags & GET_USER_PASS_PASSWORD_ONLY) == 0) { /* Read username first */ if (fgets(up->username, USER_PASS_LEN, fp) == NULL) { msg(M_FATAL, "Error reading username from %s authfile: %s", prefix, auth_file); } } chomp(up->username); if (fgets(password_buf, USER_PASS_LEN, fp) != NULL) { chomp(password_buf); } if (flags & GET_USER_PASS_PASSWORD_ONLY && !password_buf[0]) { msg(M_FATAL, "Error reading password from %s authfile: %s", prefix, auth_file); } if (password_buf[0]) { strncpy(up->password, password_buf, USER_PASS_LEN); } else { password_from_stdin = 1; } fclose(fp); if (!(flags & GET_USER_PASS_PASSWORD_ONLY) && strlen(up->username) == 0) { msg(M_FATAL, "ERROR: username from %s authfile '%s' is empty", prefix, auth_file); } } else { username_from_stdin = true; password_from_stdin = true; } /* * Get username/password from standard input? */ if (username_from_stdin || password_from_stdin || response_from_stdin) { #ifdef ENABLE_CLIENT_CR if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE) && response_from_stdin) { struct auth_challenge_info *ac = get_auth_challenge(auth_challenge, &gc); if (ac) { char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc); struct buffer packed_resp, challenge; challenge = alloc_buf_gc(14+strlen(ac->challenge_text), &gc); buf_printf(&challenge, "CHALLENGE: %s", ac->challenge_text); buf_set_write(&packed_resp, (uint8_t *)up->password, USER_PASS_LEN); if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge), response, USER_PASS_LEN, BOOL_CAST(ac->flags&CR_ECHO))) { msg(M_FATAL, "ERROR: could not read challenge response from stdin"); } strncpynt(up->username, ac->user, USER_PASS_LEN); buf_printf(&packed_resp, "CRV1::%s::%s", ac->state_id, response); } else { msg(M_FATAL, "ERROR: received malformed challenge request from server"); } } else #endif /* ifdef ENABLE_CLIENT_CR */ { struct buffer user_prompt = alloc_buf_gc(128, &gc); struct buffer pass_prompt = alloc_buf_gc(128, &gc); query_user_clear(); buf_printf(&user_prompt, "Enter %s Username:"******"Enter %s Password:"******"ERROR: Failed retrieving username or password"); } if (!(flags & GET_USER_PASS_PASSWORD_ONLY)) { if (strlen(up->username) == 0) { msg(M_FATAL, "ERROR: %s username is empty", prefix); } } #ifdef ENABLE_CLIENT_CR if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE) && response_from_stdin) { char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc); struct buffer packed_resp, challenge; char *pw64 = NULL, *resp64 = NULL; challenge = alloc_buf_gc(14+strlen(auth_challenge), &gc); buf_printf(&challenge, "CHALLENGE: %s", auth_challenge); if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge), response, USER_PASS_LEN, BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO))) { msg(M_FATAL, "ERROR: could not retrieve static challenge response"); } if (openvpn_base64_encode(up->password, strlen(up->password), &pw64) == -1 || openvpn_base64_encode(response, strlen(response), &resp64) == -1) { msg(M_FATAL, "ERROR: could not base64-encode password/static_response"); } buf_set_write(&packed_resp, (uint8_t *)up->password, USER_PASS_LEN); buf_printf(&packed_resp, "SCRV1:%s:%s", pw64, resp64); string_clear(pw64); free(pw64); string_clear(resp64); free(resp64); } #endif /* ifdef ENABLE_CLIENT_CR */ } } string_mod(up->username, CC_PRINT, CC_CRLF, 0); string_mod(up->password, CC_PRINT, CC_CRLF, 0); up->defined = true; } #if 0 msg(M_INFO, "GET_USER_PASS %s u='%s' p='%s'", prefix, up->username, up->password); #endif gc_free(&gc); return true; }