/* * read_console() - Read debug console port for user input * * INPUT * none * OUTPUT * character read from console */ char read_console(void) { char char_read = 0, str_dbg[SMALL_DEBUG_BUF]; while(1) { if(get_console_input(&char_read)) { /* print for debug only */ snprintf(str_dbg, SMALL_DEBUG_BUF, "%c\n\r", char_read); display_debug_string(str_dbg); } } return(char_read); }
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) { const bool from_stdin = (!auth_file || !strcmp (auth_file, "stdin")); 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 && ((auth_file && streq (auth_file, "management")) || (from_stdin && (flags & GET_USER_PASS_MANAGEMENT))) && management_query_user_pass_enabled (management)) { const char *sc = NULL; 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 /* * 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 (!get_console_input (BSTR (&user_prompt), true, up->password, USER_PASS_LEN)) msg (M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix); if (!strlen (up->password)) strcpy (up->password, "ok"); } /* * Get username/password from standard input? */ else if (from_stdin) { #ifndef WIN32 /* did we --daemon'ize before asking for passwords? */ if ( !isatty(0) && !isatty(2) ) { msg(M_FATAL, "neither stdin nor stderr are a tty device, can't ask for %s password. If you used --daemon, you need to use --askpass to make passphrase-protected keys work, and you can not use --auth-nocache.", prefix ); } #endif #ifdef ENABLE_CLIENT_CR if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE)) { 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; buf_set_write (&packed_resp, (uint8_t*)up->password, USER_PASS_LEN); msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", ac->challenge_text); if (!get_console_input ("Response:", BOOL_CAST(ac->flags&CR_ECHO), response, USER_PASS_LEN)) 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 { struct buffer user_prompt = alloc_buf_gc (128, &gc); struct buffer pass_prompt = alloc_buf_gc (128, &gc); buf_printf (&user_prompt, "Enter %s Username:"******"Enter %s Password:"******"ERROR: could not read %s username from stdin", prefix); if (strlen (up->username) == 0) msg (M_FATAL, "ERROR: %s username is empty", prefix); } if (!get_console_input (BSTR (&pass_prompt), false, up->password, USER_PASS_LEN)) msg (M_FATAL, "ERROR: could not not read %s password from stdin", prefix); #ifdef ENABLE_CLIENT_CR if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE)) { char *response = (char *) gc_malloc (USER_PASS_LEN, false, &gc); struct buffer packed_resp; char *pw64=NULL, *resp64=NULL; msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", auth_challenge); if (!get_console_input ("Response:", BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO), response, USER_PASS_LEN)) msg (M_FATAL, "ERROR: could not read static challenge response from stdin"); 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 } } else { /* * Get username/password from a file. */ FILE *fp; #ifndef ENABLE_PASSWORD_SAVE /* * Unless ENABLE_PASSWORD_SAVE is defined, don't allow sensitive passwords * to be read from a file. */ if (flags & GET_USER_PASS_SENSITIVE) msg (M_FATAL, "Sorry, '%s' password cannot be read from a file", prefix); #endif warn_if_group_others_accessible (auth_file); 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) { if (fgets (up->password, USER_PASS_LEN, fp) == NULL) msg (M_FATAL, "Error reading password from %s authfile: %s", prefix, auth_file); } else { if (fgets (up->username, USER_PASS_LEN, fp) == NULL || fgets (up->password, USER_PASS_LEN, fp) == NULL) msg (M_FATAL, "Error reading username and password (must be on two consecutive lines) from %s authfile: %s", prefix, auth_file); } fclose (fp); chomp (up->username); chomp (up->password); 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); } 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; }