Compare commits

..
Author SHA1 Message Date
Mounir IDRASSI cd101433c5 macOS: recover mounted volume mount points
Prefer hdiutil plist entities that carry a mount-point when recording the virtual device. This fixes APFS images where the first dev-entry is not the mounted volume.

Add a macOS mounted-volume refresh hook that recovers VirtualDevice and MountPoint from hdiutil info when FUSE-T SMB auxiliary metadata is missing or stale.
2026-05-15 15:35:28 +02:00
nkh0472andGitHub d4a237fbaf Update Language.zh-cn.xml (#1732)
* Update Language.zh-cn.xml

* Update Language.zh-cn.xml
2026-05-15 14:23:17 +09:00
Mounir IDRASSI 77e4830c99 macOS: run APFS formatter elevated
APFS volume creation can still fail with Permission denied after preparing the raw and block device aliases because newfs_apfs performs privileged APFS container and volume operations beyond opening the device nodes.

Route APFS formatting through the elevated CoreService path for non-root macOS runs. Keep the elevated interface narrow by sending only the target device and invoking user UID/GID, validate the device path on the privileged side, rebuild the formatter arguments there, and execute /sbin/newfs_apfs by absolute path to avoid PATH shadowing.

Pass -U/-G so the created filesystem preserves the invoking user ownership. Apply the same path to GUI and text-mode creation.
2026-05-15 13:52:21 +09:00
Thomas De RockerandGitHub 213dd2e74a Update Language.nl.xml (#1730)
* Update Language.nl.xml

* Update Language.nl.xml
2026-05-14 17:13:35 +09:00
PatriccolluandGitHub 22aec149de Update Corsican translation on 2026-05 (3rd) (#1728)
* Update Corsican translation on 2026-05 (3rd)

* Update Corsican translation on 2026-05 (3rd)
2026-05-14 09:19:26 +09:00
Mr-UpdateandGitHub efdfc4f273 Update Language.de.xml (#1727)
* Update Language.de.xml

- Translation completed

* Update Language.de.xml
2026-05-14 09:18:33 +09:00
17 changed files with 359 additions and 47 deletions
+6 -6
View File
@@ -6,7 +6,7 @@ Information about Corsican localization:
https://github.com/veracrypt/VeraCrypt/blob/master/Translations/Language.co.xml
2. History of Corsican translation for VeraCrypt:
- Updated in 2026 by Patriccollu di Santa Maria è Sichè: May 2nd (1.26.28), May 9th (1.26.28)
- Updated in 2026 by Patriccollu di Santa Maria è Sichè: May 2nd (1.26.28), May 9th (1.26.28), May 13th (1.26.28)
- Updated in 2025 by Patriccollu di Santa Maria è Sichè: May 5th (1.26.21), May 25th (1.26.24), June 26th (1.26.27),
Aug. 31st (1.26.27), Sep. 27th (1.26.27)
- Updated in 2024 by Patriccollu di Santa Maria è Sichè: Aug. 2nd (1.26.13), Aug. 10th (1.26.13)
@@ -1703,11 +1703,11 @@ Information about Corsican localization:
<entry lang="co" key="FORMAT_STAGE_PREPARING_TEMP_DEVICE">Cumpiimentu di a creazione di u vulume : appruntata di lapparechju timpurariu.</entry>
<entry lang="co" key="FORMAT_STAGE_CREATING_FILESYSTEM">Cumpiimentu di a creazione di u vulume : creazione di u sistema di schedarii impieghendu {0}.</entry>
<entry lang="co" key="FORMAT_STAGE_DISMOUNTING_TEMP_VOLUME">Cumpiimentu di a creazione di u vulume : smuntatura di u vulume timpurariu.</entry>
<entry lang="en" key="MACOSX_APFS_SYNTHESIZED_DEVICE">The selected device '{0}' is an APFS synthesized container or volume and cannot be used as a raw VeraCrypt volume host.\n\nSelect the physical APFS store partition{1} instead.</entry>
<entry lang="en" key="MACOSX_DEVICE_SYSTEM_PARTITION">The selected device '{0}' is a macOS system/support partition and cannot be used as a VeraCrypt volume host.</entry>
<entry lang="en" key="MACOSX_APFS_SYSTEM_STORE">The selected APFS physical store '{0}' contains the currently mounted macOS system volume and cannot be used as a VeraCrypt volume host.</entry>
<entry lang="en" key="MACOSX_DEVICE_NOT_WRITABLE">macOS reports the selected device '{0}' as read-only. Select a writable physical partition or disk.</entry>
<entry lang="en" key="MACOSX_APFS_EROFS_HINT">macOS reported the selected device as read-only. If this is an APFS disk, make sure you selected the physical APFS store partition, not an APFS synthesized volume. Use Disk Utility or 'diskutil list' to identify the physical partition, then retry.</entry>
<entry lang="co" key="MACOSX_APFS_SYNTHESIZED_DEVICE">Lapparechju selezziunatu « {0} » hè un cuntenidore o un vulume APFS sintetizatu è ùn pò micca esse impiegatu cum’è un ospite di vulume VeraCrypt di basa.\n\nSelezziunate piuttostu a partizione{1} dallucamentu APFS fisica.</entry>
<entry lang="co" key="MACOSX_DEVICE_SYSTEM_PARTITION">Lapparechju selezziunatu « {0} » hè una partizione macOS di u sistema o dassistenza è ùn pò micca esse impiegata cum’è un ospite di vulume VeraCrypt.</entry>
<entry lang="co" key="MACOSX_APFS_SYSTEM_STORE">Lallucamentu fisicu APFS selezziunatu « {0} » cuntene u vulume di u sistema macOS muntatu attualmente è ùn pò micca esse impiegatu cum’è un ospite di vulume VeraCrypt.</entry>
<entry lang="co" key="MACOSX_DEVICE_NOT_WRITABLE">macOS signaleghja lapparechju selezziunatu « {0} » cum’è essendu in lettura sola. Selezziunate una partizione fisica o un discu induve si pò scrive.</entry>
<entry lang="co" key="MACOSX_APFS_EROFS_HINT">macOS hà signalatu lapparechju selezziunatu cum’è essendu in lettura sola. Sellu hè un discu APFS, assicuratevi chì ghjè a partizione dallucamentu APFS fisica chì hè selezziunata, è micca un vulume APFS sintetizatu. Impiegate lattrezzu di discu o « diskutil list » per identificà a partizione fisica eppò pruvate torna.</entry>
</localization>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="VeraCrypt">
+5 -5
View File
@@ -1685,11 +1685,11 @@
<entry lang="de" key="FORMAT_STAGE_PREPARING_TEMP_DEVICE">Abschluss der Volume-Erstellung: Vorbereiten des temporären Geräts.</entry>
<entry lang="de" key="FORMAT_STAGE_CREATING_FILESYSTEM">Abschluss der Volume-Erstellung: Erstellen des Dateisystems mit {0}.</entry>
<entry lang="de" key="FORMAT_STAGE_DISMOUNTING_TEMP_VOLUME">Abschluss der Volume-Erstellung: Temporäres Volume wird ausgehängt.</entry>
<entry lang="en" key="MACOSX_APFS_SYNTHESIZED_DEVICE">The selected device '{0}' is an APFS synthesized container or volume and cannot be used as a raw VeraCrypt volume host.\n\nSelect the physical APFS store partition{1} instead.</entry>
<entry lang="en" key="MACOSX_DEVICE_SYSTEM_PARTITION">The selected device '{0}' is a macOS system/support partition and cannot be used as a VeraCrypt volume host.</entry>
<entry lang="en" key="MACOSX_APFS_SYSTEM_STORE">The selected APFS physical store '{0}' contains the currently mounted macOS system volume and cannot be used as a VeraCrypt volume host.</entry>
<entry lang="en" key="MACOSX_DEVICE_NOT_WRITABLE">macOS reports the selected device '{0}' as read-only. Select a writable physical partition or disk.</entry>
<entry lang="en" key="MACOSX_APFS_EROFS_HINT">macOS reported the selected device as read-only. If this is an APFS disk, make sure you selected the physical APFS store partition, not an APFS synthesized volume. Use Disk Utility or 'diskutil list' to identify the physical partition, then retry.</entry>
<entry lang="de" key="MACOSX_APFS_SYNTHESIZED_DEVICE">Das ausgewählte Gerät '{0}' ist ein synthetischer APFS-Container oder ein synthetisches APFS-Volume und kann nicht als Host für ein VeraCrypt-Raw-Volume verwendet werden.\n\nWählen Sie stattdessen die physische APFS-Speicherpartition{1} aus.</entry>
<entry lang="de" key="MACOSX_DEVICE_SYSTEM_PARTITION">Das ausgewählte Gerät '{0}' ist eine macOS-System-/Support-Partition und kann nicht als Host für ein VeraCrypt-Volume verwendet werden.</entry>
<entry lang="de" key="MACOSX_APFS_SYSTEM_STORE">Die ausgewählte physische APFS-Speicherpartition '{0}' enthält das derzeit eingebundene macOS-Systemvolume und kann nicht als VeraCrypt-Volume-Host verwendet werden.</entry>
<entry lang="de" key="MACOSX_DEVICE_NOT_WRITABLE">macOS meldet, dass das ausgewählte Gerät '{0}' schreibgeschützt ist. Wählen Sie eine beschreibbare physische Partition oder Festplatte aus.</entry>
<entry lang="de" key="MACOSX_APFS_EROFS_HINT">macOS hat das ausgewählte Gerät als schreibgeschützt gemeldet. Handelt es sich um eine APFS-Festplatte, stellen Sie sicher, dass Sie die physische APFS-Speicherpartition ausgewählt haben und nicht ein synthetisches APFS-Volume. Identifizieren Sie die physische Partition mit dem Festplatten-Dienstprogramm oder dem Befehl „diskutil list“ und versuchen Sie es dann erneut.</entry>
</localization>
<!-- XML-Schema -->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+6 -6
View File
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<VeraCrypt>
<localization prog-version="1.26.28">
<language langid="nl" name="Nederlands" en-name="Dutch" version="2026-05-08" translators="Jan van der Wal, Peter Tak, Thomas De Rocker"/>
<language langid="nl" name="Nederlands" en-name="Dutch" version="2026-05-13" translators="Jan van der Wal, Peter Tak, Thomas De Rocker"/>
<font lang="nl" class="normal" size="11" face="default"/>
<font lang="nl" class="bold" size="13" face="Arial"/>
<font lang="nl" class="fixed" size="12" face="Lucida Console"/>
@@ -1682,11 +1682,11 @@
<entry lang="nl" key="FORMAT_STAGE_PREPARING_TEMP_DEVICE">Aanmaken van volume voltooien: tijdelijk apparaat voorbereiden.</entry>
<entry lang="nl" key="FORMAT_STAGE_CREATING_FILESYSTEM">Aanmaken van volume voltooien: bestandssysteem aanmaken met {0}.</entry>
<entry lang="nl" key="FORMAT_STAGE_DISMOUNTING_TEMP_VOLUME">Aanmaken van volume voltooien: tijdelijk volume ontkoppelen.</entry>
<entry lang="en" key="MACOSX_APFS_SYNTHESIZED_DEVICE">The selected device '{0}' is an APFS synthesized container or volume and cannot be used as a raw VeraCrypt volume host.\n\nSelect the physical APFS store partition{1} instead.</entry>
<entry lang="en" key="MACOSX_DEVICE_SYSTEM_PARTITION">The selected device '{0}' is a macOS system/support partition and cannot be used as a VeraCrypt volume host.</entry>
<entry lang="en" key="MACOSX_APFS_SYSTEM_STORE">The selected APFS physical store '{0}' contains the currently mounted macOS system volume and cannot be used as a VeraCrypt volume host.</entry>
<entry lang="en" key="MACOSX_DEVICE_NOT_WRITABLE">macOS reports the selected device '{0}' as read-only. Select a writable physical partition or disk.</entry>
<entry lang="en" key="MACOSX_APFS_EROFS_HINT">macOS reported the selected device as read-only. If this is an APFS disk, make sure you selected the physical APFS store partition, not an APFS synthesized volume. Use Disk Utility or 'diskutil list' to identify the physical partition, then retry.</entry>
<entry lang="nl" key="MACOSX_APFS_SYNTHESIZED_DEVICE">Het geselecteerde apparaat {0} is een door APFS gesynthetiseerde container of een APFS-volume en kan niet worden gebruikt als host voor een onbewerkt VeraCrypt-volume.\n\nSelecteer in plaats daarvan de fysieke APFS-opslagpartitie{1}.</entry>
<entry lang="nl" key="MACOSX_DEVICE_SYSTEM_PARTITION">Het geselecteerde apparaat {0} is een systeem-/ondersteuningspartitie van macOS en kan niet worden gebruikt als host voor een VeraCrypt-volume.</entry>
<entry lang="nl" key="MACOSX_APFS_SYSTEM_STORE">De geselecteerde fysieke APFS-opslag {0} bevat het momenteel gekoppelde macOS-systeemvolume en kan niet worden gebruikt als host voor een VeraCrypt-volume.</entry>
<entry lang="nl" key="MACOSX_DEVICE_NOT_WRITABLE">macOS meldt dat het geselecteerde apparaat {0} alleen-lezen is. Selecteer een fysieke partitie of schijf waarop geschreven kan worden.</entry>
<entry lang="nl" key="MACOSX_APFS_EROFS_HINT">macOS geeft aan dat het geselecteerde apparaat alleen-lezen is. Als dit een APFS-schijf is, controleer dan of u de fysieke APFS-opslagpartitie hebt geselecteerd en niet een gesynthetiseerd APFS-volume. Gebruik Schijfhulpprogramma of diskutil list om de fysieke partitie te identificeren en probeer het vervolgens opnieuw.</entry>
</localization>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
<xs:element name="VeraCrypt">
+5 -5
View File
@@ -1683,11 +1683,11 @@
<entry lang="zh-cn" key="FORMAT_STAGE_PREPARING_TEMP_DEVICE">正在完成卷创建:准备临时设备。</entry>
<entry lang="zh-cn" key="FORMAT_STAGE_CREATING_FILESYSTEM">正在完成卷创建:使用 {0} 创建文件系统。</entry>
<entry lang="zh-cn" key="FORMAT_STAGE_DISMOUNTING_TEMP_VOLUME">正在完成卷创建:卸载临时卷。</entry>
<entry lang="en" key="MACOSX_APFS_SYNTHESIZED_DEVICE">The selected device '{0}' is an APFS synthesized container or volume and cannot be used as a raw VeraCrypt volume host.\n\nSelect the physical APFS store partition{1} instead.</entry>
<entry lang="en" key="MACOSX_DEVICE_SYSTEM_PARTITION">The selected device '{0}' is a macOS system/support partition and cannot be used as a VeraCrypt volume host.</entry>
<entry lang="en" key="MACOSX_APFS_SYSTEM_STORE">The selected APFS physical store '{0}' contains the currently mounted macOS system volume and cannot be used as a VeraCrypt volume host.</entry>
<entry lang="en" key="MACOSX_DEVICE_NOT_WRITABLE">macOS reports the selected device '{0}' as read-only. Select a writable physical partition or disk.</entry>
<entry lang="en" key="MACOSX_APFS_EROFS_HINT">macOS reported the selected device as read-only. If this is an APFS disk, make sure you selected the physical APFS store partition, not an APFS synthesized volume. Use Disk Utility or 'diskutil list' to identify the physical partition, then retry.</entry>
<entry lang="zh-cn" key="MACOSX_APFS_SYNTHESIZED_DEVICE">所选设备 '{0}' APFS 合成容器或卷,不能作为原始 VeraCrypt 卷的承载设备使用。\n\n请改选物理 APFS 存储分区{1}。</entry>
<entry lang="zh-cn" key="MACOSX_DEVICE_SYSTEM_PARTITION">所选设备 '{0}' macOS 系统/支持分区,无法作为 VeraCrypt 卷主机使用。</entry>
<entry lang="zh-cn" key="MACOSX_APFS_SYSTEM_STORE">所选 APFS 物理存储 '{0}' 包含当前挂载的 macOS 系统卷,无法作为 VeraCrypt 卷主机使用。</entry>
<entry lang="zh-cn" key="MACOSX_DEVICE_NOT_WRITABLE">macOS 报告所选设备 '{0}' 为只读。请选择可写的物理分区或磁盘。</entry>
<entry lang="zh-cn" key="MACOSX_APFS_EROFS_HINT">macOS 报告所选设备为只读。如果这是 APFS 磁盘,请确保您选择的是物理 APFS 存储分区,而不是 APFS 合成卷。请使用“磁盘工具”或 'diskutil list' 来识别物理分区,然后重试。</entry>
</localization>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="VeraCrypt">
+85
View File
@@ -20,6 +20,7 @@
#include "Platform/SystemLog.h"
#include "Platform/Thread.h"
#include "Platform/Unix/Poller.h"
#include "Platform/Unix/Process.h"
#include "Core/Core.h"
#include "CoreUnix.h"
#include "CoreServiceRequest.h"
@@ -27,6 +28,66 @@
namespace VeraCrypt
{
#ifdef TC_MACOSX
static bool IsMacOSXDevicePathWithPrefix (const string &path, const string &prefix)
{
if (path.find (prefix) != 0 || path.size() <= prefix.size())
return false;
size_t index = prefix.size();
while (index < path.size() && path[index] >= '0' && path[index] <= '9')
++index;
if (index == prefix.size())
return false;
if (index == path.size())
return true;
if (path[index++] != 's')
return false;
size_t sliceStart = index;
while (index < path.size() && path[index] >= '0' && path[index] <= '9')
++index;
return index > sliceStart && index == path.size();
}
static bool IsMacOSXFormatterDevicePath (const string &path)
{
return IsMacOSXDevicePathWithPrefix (path, "/dev/disk")
|| IsMacOSXDevicePathWithPrefix (path, "/dev/rdisk");
}
static list <string> BuildMacOSXAPFSFormatterArguments (const ExecuteMacOSXAPFSFormatterRequest &request)
{
if (!IsMacOSXFormatterDevicePath (request.Device))
throw ParameterIncorrect (SRC_POS);
if (request.OwnerUserId > static_cast <uint64> ((uid_t) -1)
|| request.OwnerGroupId > static_cast <uint64> ((gid_t) -1))
{
throw ParameterIncorrect (SRC_POS);
}
stringstream uid;
stringstream gid;
list <string> arguments;
uid << request.OwnerUserId;
gid << request.OwnerGroupId;
arguments.push_back ("-U");
arguments.push_back (uid.str());
arguments.push_back ("-G");
arguments.push_back (gid.str());
arguments.push_back (string (request.Device));
return arguments;
}
#endif
template <class T>
unique_ptr <T> CoreService::GetResponse ()
{
@@ -201,6 +262,17 @@ namespace VeraCrypt
continue;
}
#ifdef TC_MACOSX
// ExecuteMacOSXAPFSFormatterRequest
ExecuteMacOSXAPFSFormatterRequest *executeAPFSFormatterRequest = dynamic_cast <ExecuteMacOSXAPFSFormatterRequest*> (request.get());
if (executeAPFSFormatterRequest)
{
Process::Execute (CoreService::GetMacOSXAPFSFormatterPath(), BuildMacOSXAPFSFormatterArguments (*executeAPFSFormatterRequest));
ExecuteMacOSXAPFSFormatterResponse().Serialize (outputStream);
continue;
}
#endif
// MountVolumeRequest
MountVolumeRequest *mountRequest = dynamic_cast <MountVolumeRequest*> (request.get());
if (mountRequest)
@@ -290,6 +362,19 @@ namespace VeraCrypt
return SendRequest <GetHostDevicesResponse> (request)->HostDevices;
}
#ifdef TC_MACOSX
const char *CoreService::GetMacOSXAPFSFormatterPath ()
{
return "/sbin/newfs_apfs";
}
void CoreService::RequestExecuteMacOSXAPFSFormatter (const DevicePath &devicePath, uint64 userId, uint64 groupId)
{
ExecuteMacOSXAPFSFormatterRequest request (devicePath, userId, groupId);
SendRequest <ExecuteMacOSXAPFSFormatterResponse> (request);
}
#endif
shared_ptr <VolumeInfo> CoreService::RequestMountVolume (MountOptions &options)
{
MountVolumeRequest request (&options);
+4
View File
@@ -35,6 +35,10 @@ namespace VeraCrypt
static uint32 RequestGetDeviceSectorSize (const DevicePath &devicePath);
static uint64 RequestGetDeviceSize (const DevicePath &devicePath);
static HostDeviceList RequestGetHostDevices (bool pathListOnly);
#ifdef TC_MACOSX
static const char *GetMacOSXAPFSFormatterPath ();
static void RequestExecuteMacOSXAPFSFormatter (const DevicePath &devicePath, uint64 userId, uint64 groupId);
#endif
static shared_ptr <VolumeInfo> RequestMountVolume (MountOptions &options);
static void RequestSetFileOwner (const FilesystemPath &path, const UserId &owner);
static void SetAdminPasswordCallback (shared_ptr <GetStringFunctor> functor) { AdminPasswordCallback = functor; }
+29
View File
@@ -219,6 +219,32 @@ namespace VeraCrypt
CoreServiceRequest::Serialize (stream);
}
#ifdef TC_MACOSX
// ExecuteMacOSXAPFSFormatterRequest
void ExecuteMacOSXAPFSFormatterRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
Device = sr.DeserializeWString ("Device");
sr.Deserialize ("OwnerGroupId", OwnerGroupId);
sr.Deserialize ("OwnerUserId", OwnerUserId);
}
bool ExecuteMacOSXAPFSFormatterRequest::RequiresElevation () const
{
return !Core->HasAdminPrivileges();
}
void ExecuteMacOSXAPFSFormatterRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("Device", wstring (Device));
sr.Serialize ("OwnerGroupId", OwnerGroupId);
sr.Serialize ("OwnerUserId", OwnerUserId);
}
#endif
// MountVolumeRequest
void MountVolumeRequest::Deserialize (shared_ptr <Stream> stream)
{
@@ -294,6 +320,9 @@ namespace VeraCrypt
TC_SERIALIZER_FACTORY_ADD_CLASS (EmergencyDismountVolumeRequest);
#endif
TC_SERIALIZER_FACTORY_ADD_CLASS (ExitRequest);
#ifdef TC_MACOSX
TC_SERIALIZER_FACTORY_ADD_CLASS (ExecuteMacOSXAPFSFormatterRequest);
#endif
TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSectorSizeRequest);
TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSizeRequest);
TC_SERIALIZER_FACTORY_ADD_CLASS (GetHostDevicesRequest);
+16
View File
@@ -126,6 +126,22 @@ namespace VeraCrypt
TC_SERIALIZABLE (ExitRequest);
};
#ifdef TC_MACOSX
struct ExecuteMacOSXAPFSFormatterRequest : CoreServiceRequest
{
ExecuteMacOSXAPFSFormatterRequest () { }
ExecuteMacOSXAPFSFormatterRequest (const DevicePath &devicePath, uint64 userId, uint64 groupId)
: Device (devicePath), OwnerGroupId (groupId), OwnerUserId (userId) { }
TC_SERIALIZABLE (ExecuteMacOSXAPFSFormatterRequest);
virtual bool RequiresElevation () const;
DevicePath Device;
uint64 OwnerGroupId;
uint64 OwnerUserId;
};
#endif
struct MountVolumeRequest : CoreServiceRequest
{
MountVolumeRequest () { }
+15
View File
@@ -88,6 +88,18 @@ namespace VeraCrypt
Serializable::SerializeList (stream, HostDevices);
}
#ifdef TC_MACOSX
// ExecuteMacOSXAPFSFormatterResponse
void ExecuteMacOSXAPFSFormatterResponse::Deserialize (shared_ptr <Stream> stream)
{
}
void ExecuteMacOSXAPFSFormatterResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
}
#endif
// MountVolumeResponse
void MountVolumeResponse::Deserialize (shared_ptr <Stream> stream)
{
@@ -118,6 +130,9 @@ namespace VeraCrypt
TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSectorSizeResponse);
TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSizeResponse);
TC_SERIALIZER_FACTORY_ADD_CLASS (GetHostDevicesResponse);
#ifdef TC_MACOSX
TC_SERIALIZER_FACTORY_ADD_CLASS (ExecuteMacOSXAPFSFormatterResponse);
#endif
TC_SERIALIZER_FACTORY_ADD_CLASS (MountVolumeResponse);
TC_SERIALIZER_FACTORY_ADD_CLASS (SetFileOwnerResponse);
}
+8
View File
@@ -69,6 +69,14 @@ namespace VeraCrypt
HostDeviceList HostDevices;
};
#ifdef TC_MACOSX
struct ExecuteMacOSXAPFSFormatterResponse : CoreServiceResponse
{
ExecuteMacOSXAPFSFormatterResponse () { }
TC_SERIALIZABLE (ExecuteMacOSXAPFSFormatterResponse);
};
#endif
struct MountVolumeResponse : CoreServiceResponse
{
MountVolumeResponse () { }
+4 -1
View File
@@ -594,7 +594,7 @@ namespace VeraCrypt
mountedVol->AuxMountPoint = mf.MountPoint;
if (!mountedVol->VirtualDevice.IsEmpty())
if (mountedVol->MountPoint.IsEmpty() && !mountedVol->VirtualDevice.IsEmpty())
{
MountedFilesystemList mpl = GetMountedFilesystems (mountedVol->VirtualDevice);
@@ -602,6 +602,9 @@ namespace VeraCrypt
mountedVol->MountPoint = mpl.front()->MountPoint;
}
if (mountedVol->MountPoint.IsEmpty() || mountedVol->VirtualDevice.IsEmpty())
UpdateMountedVolumeInfo (mountedVol);
volumes.push_back (mountedVol);
if (!volumePath.IsEmpty())
+1
View File
@@ -73,6 +73,7 @@ namespace VeraCrypt
virtual void MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const;
virtual DevicePath MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const;
virtual void MountVolumeNative (shared_ptr <Volume> volume, MountOptions &options, const DirectoryPath &auxMountPoint) const { throw NotApplicable (SRC_POS); }
virtual void UpdateMountedVolumeInfo (shared_ptr <VolumeInfo> mountedVolume) const { (void) mountedVolume; }
#ifdef TC_LINUX
string DetectFilesystemType (const DevicePath &devicePath) const;
#endif
+107 -22
View File
@@ -77,6 +77,7 @@ namespace VeraCrypt
static bool ExtractPlistString (const string &xml, const string &key, size_t start, size_t limit, string &value, size_t *endPos = nullptr)
{
// hdiutil currently emits simple <key>name</key><string>value</string> pairs.
// This lightweight parser assumes the value follows the requested key.
string keyTag = "<key>" + key + "</key>";
size_t p = xml.find (keyTag, start);
if (p == string::npos || p >= limit)
@@ -124,7 +125,64 @@ namespace VeraCrypt
return normalized;
}
static DevicePath FindVirtualDeviceByImagePath (const string &imagePath)
static bool ExtractDiskImageDeviceAndMountPoint (const string &xml, size_t start, size_t limit, DevicePath &device, DirectoryPath &mountPoint)
{
string firstDevice;
string mountedDevice;
string mountedPath;
for (size_t p = start; ; )
{
size_t devKeyPos = xml.find ("<key>dev-entry</key>", p);
if (devKeyPos == string::npos || devKeyPos >= limit)
break;
string devEntry;
size_t devValueEnd = 0;
if (!ExtractPlistString (xml, "dev-entry", devKeyPos, limit, devEntry, &devValueEnd))
{
p = devKeyPos + 1;
continue;
}
devEntry = StringConverter::Trim (devEntry);
if (firstDevice.empty())
firstDevice = devEntry;
size_t nextDevKeyPos = xml.find ("<key>dev-entry</key>", devValueEnd);
if (nextDevKeyPos == string::npos || nextDevKeyPos > limit)
nextDevKeyPos = limit;
string currentMountPoint;
// hdiutil currently emits dev-entry before mount-point inside each entity.
if (ExtractPlistString (xml, "mount-point", devValueEnd, nextDevKeyPos, currentMountPoint)
&& !currentMountPoint.empty())
{
mountedDevice = devEntry;
mountedPath = currentMountPoint;
break;
}
p = devValueEnd;
}
if (!mountedDevice.empty())
{
device = mountedDevice;
mountPoint = mountedPath;
return true;
}
if (!firstDevice.empty())
{
device = firstDevice;
return true;
}
return false;
}
static bool FindDiskImageInfoByImagePath (const string &imagePath, DevicePath &device, DirectoryPath &mountPoint)
{
list <string> args;
args.push_back ("info");
@@ -150,15 +208,13 @@ namespace VeraCrypt
size_t nextImageKeyPos = xml.find ("<key>image-path</key>", imageValueEnd);
if (NormalizeDiskImagePath (currentImagePath) == normalizedImagePath)
{
string devEntry;
if (ExtractPlistString (xml, "dev-entry", imageValueEnd, nextImageKeyPos, devEntry))
return StringConverter::Trim (devEntry);
return ExtractDiskImageDeviceAndMountPoint (xml, imageValueEnd, nextImageKeyPos, device, mountPoint);
}
p = imageValueEnd;
}
return DevicePath();
return false;
}
static bool AuxiliaryControlFileHasVirtualDevice (const DirectoryPath &auxMountPoint, const DevicePath &virtualDev, int retryCount = 50)
@@ -198,13 +254,11 @@ namespace VeraCrypt
shared_ptr <VolumeInfo> CoreMacOSX::DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo)
{
if (mountedVolume->VirtualDevice.IsEmpty() && !mountedVolume->AuxMountPoint.IsEmpty())
if (!mountedVolume->AuxMountPoint.IsEmpty())
{
try
{
DevicePath recoveredVirtualDevice = FindVirtualDeviceByImagePath (string (mountedVolume->AuxMountPoint) + FuseService::GetVolumeImagePath());
if (!recoveredVirtualDevice.IsEmpty())
mountedVolume->VirtualDevice = recoveredVirtualDevice;
UpdateMountedVolumeInfo (mountedVolume);
}
catch (...) { }
}
@@ -277,6 +331,45 @@ namespace VeraCrypt
return mountedVolume;
}
void CoreMacOSX::UpdateMountedVolumeInfo (shared_ptr <VolumeInfo> mountedVolume) const
{
if (!mountedVolume || mountedVolume->AuxMountPoint.IsEmpty())
return;
try
{
DevicePath recoveredVirtualDevice;
DirectoryPath recoveredMountPoint;
if (FindDiskImageInfoByImagePath (string (mountedVolume->AuxMountPoint) + FuseService::GetVolumeImagePath(), recoveredVirtualDevice, recoveredMountPoint))
{
if (!recoveredVirtualDevice.IsEmpty())
{
if (mountedVolume->VirtualDevice != recoveredVirtualDevice && recoveredMountPoint.IsEmpty())
mountedVolume->MountPoint = DirectoryPath();
mountedVolume->VirtualDevice = recoveredVirtualDevice;
}
if (!recoveredMountPoint.IsEmpty())
mountedVolume->MountPoint = recoveredMountPoint;
}
}
catch (...) { }
if (mountedVolume->MountPoint.IsEmpty() && !mountedVolume->VirtualDevice.IsEmpty())
{
try
{
MountedFilesystemList mountedFilesystems = GetMountedFilesystems (mountedVolume->VirtualDevice);
if (mountedFilesystems.size() > 0)
mountedVolume->MountPoint = mountedFilesystems.front()->MountPoint;
}
catch (...) { }
}
}
void CoreMacOSX::CheckFilesystem (shared_ptr <VolumeInfo> mountedVolume, bool repair) const
{
list <string> args;
@@ -378,20 +471,12 @@ namespace VeraCrypt
}
}
size_t p = xml.find ("<key>dev-entry</key>");
if (p == string::npos)
DevicePath virtualDev;
DirectoryPath mountPoint;
if (!ExtractDiskImageDeviceAndMountPoint (xml, 0, string::npos, virtualDev, mountPoint)
|| virtualDev.IsEmpty())
throw ParameterIncorrect (SRC_POS);
p = xml.find ("<string>", p);
if (p == string::npos)
throw ParameterIncorrect (SRC_POS);
p += 8;
size_t e = xml.find ("</string>", p);
if (e == string::npos)
throw ParameterIncorrect (SRC_POS);
DevicePath virtualDev = StringConverter::Trim (xml.substr (p, e - p));
(void) mountPoint;
try
{
+1
View File
@@ -30,6 +30,7 @@ namespace VeraCrypt
protected:
virtual DevicePath MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const;
virtual void UpdateMountedVolumeInfo (shared_ptr <VolumeInfo> mountedVolume) const;
private:
CoreMacOSX (const CoreMacOSX &);
+12 -1
View File
@@ -843,7 +843,9 @@ namespace VeraCrypt
{
RestoreMacOSXFormatterDeviceOwners (*finally_arg);
});
PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners);
bool useElevatedAPFSFormatter = UseElevatedMacOSXAPFSFormatter (fsFormatter);
if (!useElevatedAPFSFormatter)
PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners);
#else
UserId origDeviceOwner ((uid_t) -1);
@@ -888,10 +890,19 @@ namespace VeraCrypt
}
}
#ifdef TC_MACOSX
if (IsMacOSXAPFSFormatter (fsFormatter) && !useElevatedAPFSFormatter)
AddMacOSXAPFSFormatterUserArgs (args);
#endif
args.push_back (string (virtualDevice));
SetCreationProgressText (StringFormatter (LangString["FORMAT_STAGE_CREATING_FILESYSTEM"], fsFormatter));
#ifdef TC_MACOSX
ExecuteMacOSXFilesystemFormatter (fsFormatter, args);
#else
Process::Execute (fsFormatter, args);
#endif
SetCreationProgressText (LangString["FORMAT_STAGE_DISMOUNTING_TEMP_VOLUME"]);
}
#endif // TC_UNIX
+43
View File
@@ -14,6 +14,8 @@
#ifdef TC_MACOSX
#include <unistd.h>
#include "Core/Unix/CoreService.h"
#include "Platform/Unix/Process.h"
namespace VeraCrypt
{
@@ -59,6 +61,33 @@ namespace VeraCrypt
return deviceIdentifier;
}
inline bool IsMacOSXAPFSFormatter (const string &fsFormatter)
{
size_t namePos = fsFormatter.find_last_of ('/');
string fsFormatterName = namePos == string::npos ? fsFormatter : fsFormatter.substr (namePos + 1);
return fsFormatterName == "newfs_apfs";
}
inline bool UseElevatedMacOSXAPFSFormatter (const string &fsFormatter)
{
return IsMacOSXAPFSFormatter (fsFormatter) && !Core->HasAdminPrivileges();
}
inline void AddMacOSXAPFSFormatterUserArgs (list <string> &args)
{
stringstream uid;
stringstream gid;
// The APFS formatter may run elevated, so preserve the invoking user's ownership.
uid << getuid();
gid << getgid();
args.push_back ("-U");
args.push_back (uid.str());
args.push_back ("-G");
args.push_back (gid.str());
}
struct MacOSXFormatterDeviceOwnerRestore
{
MacOSXFormatterDeviceOwnerRestore (const FilesystemPath &path, const UserId &owner)
@@ -125,6 +154,20 @@ namespace VeraCrypt
catch (...) { }
}
}
inline void ExecuteMacOSXFilesystemFormatter (const string &fsFormatter, const list <string> &args)
{
if (UseElevatedMacOSXAPFSFormatter (fsFormatter))
{
if (args.empty())
throw ParameterIncorrect (SRC_POS);
CoreService::RequestExecuteMacOSXAPFSFormatter (DevicePath (args.back()), getuid(), getgid());
return;
}
Process::Execute (IsMacOSXAPFSFormatter (fsFormatter) ? CoreService::GetMacOSXAPFSFormatterPath() : fsFormatter, args);
}
}
#endif // TC_MACOSX
+12 -1
View File
@@ -1078,7 +1078,9 @@ namespace VeraCrypt
{
RestoreMacOSXFormatterDeviceOwners (*finally_arg);
});
PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners);
bool useElevatedAPFSFormatter = UseElevatedMacOSXAPFSFormatter (fsFormatter);
if (!useElevatedAPFSFormatter)
PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners);
#else
UserId origDeviceOwner ((uid_t) -1);
@@ -1123,9 +1125,18 @@ namespace VeraCrypt
}
}
#ifdef TC_MACOSX
if (IsMacOSXAPFSFormatter (fsFormatter) && !useElevatedAPFSFormatter)
AddMacOSXAPFSFormatterUserArgs (args);
#endif
args.push_back (string (virtualDevice));
#ifdef TC_MACOSX
ExecuteMacOSXFilesystemFormatter (fsFormatter, args);
#else
Process::Execute (fsFormatter, args);
#endif
}
#endif // TC_UNIX