mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-06-09 21:22:41 +00:00
Linux/macOS: surface post-sudo elevation errors
Separate sudo authentication success from elevated request execution state by acknowledging when the elevated core service starts successfully. Once that channel is available, propagate later failures instead of showing repeated administrator password dialogs. Initialize the sudo dummy-password flag consistently on macOS, avoiding an uninitialized read of UseDummySudoPassword. Register admin-password cleanup before elevation attempts so plaintext sudo credentials are erased on early-return and post-sudo failure paths. References #1788.
This commit is contained in:
@@ -20,9 +20,7 @@ namespace VeraCrypt
|
||||
{
|
||||
CoreBase::CoreBase ()
|
||||
: DeviceChangeInProgress (false)
|
||||
#if defined(TC_LINUX ) || defined (TC_FREEBSD)
|
||||
, UseDummySudoPassword (false)
|
||||
#endif
|
||||
#if defined(TC_UNIX)
|
||||
,AllowInsecureMount (false)
|
||||
#endif
|
||||
|
||||
@@ -110,8 +110,7 @@ namespace VeraCrypt
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
unique_ptr <T> CoreService::GetResponse ()
|
||||
unique_ptr <Serializable> CoreService::GetResponseObject ()
|
||||
{
|
||||
unique_ptr <Serializable> deserializedObject (Serializable::DeserializeNew (ServiceOutputStream));
|
||||
|
||||
@@ -119,6 +118,14 @@ namespace VeraCrypt
|
||||
if (deserializedException)
|
||||
deserializedException->Throw();
|
||||
|
||||
return deserializedObject;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
unique_ptr <T> CoreService::GetResponse ()
|
||||
{
|
||||
unique_ptr <Serializable> deserializedObject (GetResponseObject());
|
||||
|
||||
if (dynamic_cast <T *> (deserializedObject.get()) == nullptr)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
@@ -199,14 +206,21 @@ namespace VeraCrypt
|
||||
|
||||
if (!ElevatedPrivileges && request->ElevateUserPrivileges)
|
||||
{
|
||||
bool elevatedServiceStarted = false;
|
||||
|
||||
if (!ElevatedServiceAvailable)
|
||||
{
|
||||
finally_do_arg (string *, &request->AdminPassword, { StringConverter::Erase (*finally_arg); });
|
||||
|
||||
CoreService::StartElevated (*request);
|
||||
ElevatedServiceAvailable = true;
|
||||
elevatedServiceStarted = true;
|
||||
}
|
||||
|
||||
// Report sudo/elevated-service success before executing the request.
|
||||
if (elevatedServiceStarted)
|
||||
ElevatedServiceStartedResponse().Serialize (outputStream);
|
||||
|
||||
request->Serialize (ServiceInputStream);
|
||||
GetResponse <Serializable>()->Serialize (outputStream);
|
||||
continue;
|
||||
@@ -424,6 +438,7 @@ namespace VeraCrypt
|
||||
request.UserEnvPATH = Core->GetUserEnvPATH();
|
||||
request.UseDummySudoPassword = Core->GetUseDummySudoPassword();
|
||||
request.AllowInsecureMount = Core->GetAllowInsecureMount();
|
||||
finally_do_arg (string *, &request.AdminPassword, { StringConverter::Erase (*finally_arg); });
|
||||
|
||||
if (request.RequiresElevation())
|
||||
{
|
||||
@@ -482,12 +497,28 @@ namespace VeraCrypt
|
||||
try
|
||||
{
|
||||
request.Serialize (ServiceInputStream);
|
||||
unique_ptr <T> response (GetResponse <T>());
|
||||
|
||||
unique_ptr <Serializable> response (GetResponseObject());
|
||||
if (dynamic_cast <ElevatedServiceStartedResponse *> (response.get()) != nullptr)
|
||||
{
|
||||
// The elevated channel is usable even if the forwarded request fails.
|
||||
// Any later failure must be propagated as the real error rather than
|
||||
// triggering another administrator-password prompt.
|
||||
ElevatedServiceAvailable = true;
|
||||
return GetResponse <T> ();
|
||||
}
|
||||
|
||||
if (dynamic_cast <T *> (response.get()) == nullptr)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
ElevatedServiceAvailable = true;
|
||||
return response;
|
||||
return unique_ptr <T> (dynamic_cast <T *> (response.release()));
|
||||
}
|
||||
catch (ElevationFailed &e)
|
||||
{
|
||||
if (ElevatedServiceAvailable)
|
||||
throw;
|
||||
|
||||
if (!request.FastElevation)
|
||||
{
|
||||
ExceptionEventArgs args (e);
|
||||
@@ -502,8 +533,6 @@ namespace VeraCrypt
|
||||
}
|
||||
}
|
||||
|
||||
finally_do_arg (string *, &request.AdminPassword, { StringConverter::Erase (*finally_arg); });
|
||||
|
||||
request.Serialize (ServiceInputStream);
|
||||
return GetResponse <T>();
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace VeraCrypt
|
||||
static void Stop ();
|
||||
|
||||
protected:
|
||||
static unique_ptr <Serializable> GetResponseObject ();
|
||||
template <class T> static unique_ptr <T> GetResponse ();
|
||||
template <class T> static unique_ptr <T> SendRequest (CoreServiceRequest &request);
|
||||
static void StartElevated (const CoreServiceRequest &request);
|
||||
|
||||
@@ -15,6 +15,16 @@
|
||||
|
||||
namespace VeraCrypt
|
||||
{
|
||||
// ElevatedServiceStartedResponse
|
||||
void ElevatedServiceStartedResponse::Deserialize (shared_ptr <Stream> stream)
|
||||
{
|
||||
}
|
||||
|
||||
void ElevatedServiceStartedResponse::Serialize (shared_ptr <Stream> stream) const
|
||||
{
|
||||
Serializable::Serialize (stream);
|
||||
}
|
||||
|
||||
// CheckFilesystemResponse
|
||||
void CheckFilesystemResponse::Deserialize (shared_ptr <Stream> stream)
|
||||
{
|
||||
@@ -124,6 +134,7 @@ namespace VeraCrypt
|
||||
Serializable::Serialize (stream);
|
||||
}
|
||||
|
||||
TC_SERIALIZER_FACTORY_ADD_CLASS (ElevatedServiceStartedResponse);
|
||||
TC_SERIALIZER_FACTORY_ADD_CLASS (CheckFilesystemResponse);
|
||||
TC_SERIALIZER_FACTORY_ADD_CLASS (DismountFilesystemResponse);
|
||||
TC_SERIALIZER_FACTORY_ADD_CLASS (DismountVolumeResponse);
|
||||
|
||||
@@ -22,6 +22,12 @@ namespace VeraCrypt
|
||||
{
|
||||
};
|
||||
|
||||
struct ElevatedServiceStartedResponse : CoreServiceResponse
|
||||
{
|
||||
ElevatedServiceStartedResponse () { }
|
||||
TC_SERIALIZABLE (ElevatedServiceStartedResponse);
|
||||
};
|
||||
|
||||
struct CheckFilesystemResponse : CoreServiceResponse
|
||||
{
|
||||
CheckFilesystemResponse () { }
|
||||
|
||||
Reference in New Issue
Block a user