VirtualBox

source: vbox/trunk/src/VBox/Frontends/Common/PasswordInput.cpp

Last change on this file was 98103, checked in by vboxsync, 18 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.3 KB
Line 
1/* $Id: PasswordInput.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * Frontend shared bits - Password file and console input helpers.
4 */
5
6/*
7 * Copyright (C) 2012-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include "PasswordInput.h"
33
34#include <iprt/ctype.h>
35#include <iprt/errcore.h>
36#include <iprt/message.h>
37#include <iprt/stream.h>
38
39#include <VBox/com/errorprint.h>
40
41
42/**
43 * Reads a password from the password file.
44 *
45 * Only first line is used. The passwords length must be less than 512 bytes
46 *
47 * @param pszFilename The path to file containing the password
48 * @param pPasswd The string where password will be returned
49 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg.
50 */
51RTEXITCODE readPasswordFile(const char *pszFilename, com::Utf8Str *pPasswd)
52{
53 size_t cbFile;
54 char szPasswd[512] = { 0 };
55 int vrc = VINF_SUCCESS;
56 RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
57 bool fStdIn = !strcmp(pszFilename, "stdin");
58 PRTSTREAM pStrm;
59 if (!fStdIn)
60 vrc = RTStrmOpen(pszFilename, "r", &pStrm);
61 else
62 pStrm = g_pStdIn;
63 if (RT_SUCCESS(vrc))
64 {
65 vrc = RTStrmReadEx(pStrm, szPasswd, sizeof(szPasswd)-1, &cbFile);
66 if (RT_SUCCESS(vrc))
67 {
68 size_t cbSize = RT_MIN(sizeof(szPasswd)-1, cbFile);
69 unsigned i;
70 for (i = 0; i < cbSize && !RTLocCIsCntrl(szPasswd[i]); i++)
71 ;
72 szPasswd[i] = '\0';
73 /* If the line containing password doesn't fit into buffer */
74 if (i >= sizeof(szPasswd)-1 && cbFile >= sizeof(szPasswd))
75 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Provided password in file '%s' is too long", pszFilename);
76 else
77 *pPasswd = szPasswd;
78 }
79 else
80 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Cannot read password from file '%s': %Rrc", pszFilename, vrc);
81 if (!fStdIn)
82 RTStrmClose(pStrm);
83 }
84 else
85 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Cannot open password file '%s' (%Rrc)", pszFilename, vrc);
86
87 return rcExit;
88}
89
90
91/**
92 * Sets password for settings from password file
93 *
94 * Only first line is used. The passwords length must be less than 512 bytes
95 *
96 * @param virtualBox The IVirtualBox interface the settings password will be set for
97 * @param pszFilename The path to file containing the password
98 * @return RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg.
99 */
100RTEXITCODE settingsPasswordFile(ComPtr<IVirtualBox> virtualBox, const char *pszFilename)
101{
102 com::Utf8Str passwd;
103 RTEXITCODE rcExit = readPasswordFile(pszFilename, &passwd);
104 if (rcExit == RTEXITCODE_SUCCESS)
105 {
106 HRESULT hrc;
107 CHECK_ERROR(virtualBox, SetSettingsSecret(com::Bstr(passwd).raw()));
108 if (FAILED(hrc))
109 rcExit = RTEXITCODE_FAILURE;
110 }
111
112 return rcExit;
113}
114
115
116/**
117 * Gets the password from the user input
118 * *
119 * @param pPassword The string where password will be returned
120 * @param pszPrompt The prompt string for user
121 * @return RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg.
122 */
123RTEXITCODE readPasswordFromConsole(com::Utf8Str *pPassword, const char *pszPrompt, ...)
124{
125 RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
126 char aszPwdInput[_1K] = { 0 };
127 va_list vaArgs;
128
129 va_start(vaArgs, pszPrompt);
130 int vrc = RTStrmPrintfV(g_pStdOut, pszPrompt, vaArgs);
131 if (RT_SUCCESS(vrc))
132 {
133 bool fEchoOld = false;
134 vrc = RTStrmInputGetEchoChars(g_pStdIn, &fEchoOld);
135 if (RT_SUCCESS(vrc))
136 {
137 vrc = RTStrmInputSetEchoChars(g_pStdIn, false);
138 if (RT_SUCCESS(vrc))
139 {
140 vrc = RTStrmGetLine(g_pStdIn, &aszPwdInput[0], sizeof(aszPwdInput));
141 if (RT_SUCCESS(vrc))
142 {
143#ifdef RT_OS_WINDOWS
144 /*
145 * Returned string encoded in console code page (e.g. Win-125X or CP-XXX).
146 * Convert it to Utf-8
147 */
148 char *pszPassword = NULL;
149 vrc = RTStrConsoleCPToUtf8(&pszPassword, aszPwdInput);
150 if (RT_SUCCESS(vrc) && pszPassword)
151 {
152 *pPassword = pszPassword;
153 RTMemFree(pszPassword);
154 }
155 else
156 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE,
157 "Failed to convert password from windows console codepage to Utf-8 (%Rrc)",
158 vrc);
159#else
160 *pPassword = aszPwdInput;
161#endif
162 }
163 else
164 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed read password from command line (%Rrc)", vrc);
165
166 int vrc2 = RTStrmInputSetEchoChars(g_pStdIn, fEchoOld);
167 AssertRC(vrc2);
168 }
169 else
170 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to disable echoing typed characters (%Rrc)", vrc);
171 }
172 else
173 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to retrieve echo setting (%Rrc)", vrc);
174
175 RTStrmPutStr(g_pStdOut, "\n");
176 }
177 else
178 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to print prompt (%Rrc)", vrc);
179 va_end(vaArgs);
180
181 return rcExit;
182}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use