diff options
Diffstat (limited to 'src/Core/Unix')
-rw-r--r-- | src/Core/Unix/CoreService.cpp | 8 | ||||
-rw-r--r-- | src/Core/Unix/CoreUnix.cpp | 49 | ||||
-rw-r--r-- | src/Core/Unix/FreeBSD/CoreFreeBSD.cpp | 47 | ||||
-rw-r--r-- | src/Core/Unix/Linux/CoreLinux.cpp | 14 | ||||
-rw-r--r-- | src/Core/Unix/MacOSX/CoreMacOSX.cpp | 11 |
5 files changed, 105 insertions, 24 deletions
diff --git a/src/Core/Unix/CoreService.cpp b/src/Core/Unix/CoreService.cpp index e543652a..6d0f05e5 100644 --- a/src/Core/Unix/CoreService.cpp +++ b/src/Core/Unix/CoreService.cpp @@ -30,61 +30,61 @@ namespace VeraCrypt template <class T> unique_ptr <T> CoreService::GetResponse () { unique_ptr <Serializable> deserializedObject (Serializable::DeserializeNew (ServiceOutputStream)); Exception *deserializedException = dynamic_cast <Exception*> (deserializedObject.get()); if (deserializedException) deserializedException->Throw(); if (dynamic_cast <T *> (deserializedObject.get()) == nullptr) throw ParameterIncorrect (SRC_POS); return unique_ptr <T> (dynamic_cast <T *> (deserializedObject.release())); } void CoreService::ProcessElevatedRequests () { int pid = fork(); throw_sys_if (pid == -1); if (pid == 0) { try { int f = open ("/dev/null", 0); throw_sys_sub_if (f == -1, "/dev/null"); throw_sys_if (dup2 (f, STDERR_FILENO) == -1); // Wait for sync code while (true) { - byte b; + uint8 b; throw_sys_if (read (STDIN_FILENO, &b, 1) != 1); if (b != 0x00) continue; throw_sys_if (read (STDIN_FILENO, &b, 1) != 1); if (b != 0x11) continue; throw_sys_if (read (STDIN_FILENO, &b, 1) != 1); if (b == 0x22) break; } ElevatedPrivileges = true; ProcessRequests (STDIN_FILENO, STDOUT_FILENO); _exit (0); } catch (exception &e) { #ifdef DEBUG SystemLog::WriteException (e); #endif } catch (...) { } _exit (1); } } void CoreService::ProcessRequests (int inputFD, int outputFD) { @@ -282,61 +282,61 @@ namespace VeraCrypt { static Mutex mutex; ScopeLock lock (mutex); if (request.RequiresElevation()) { request.ElevateUserPrivileges = true; request.FastElevation = !ElevatedServiceAvailable; request.ApplicationExecutablePath = Core->GetApplicationExecutablePath(); while (!ElevatedServiceAvailable) { // Test if the user has an active "sudo" session. // This is only done under Linux / FreeBSD by executing the command 'sudo -n uptime'. // In case a "sudo" session is active, the result of the command contains the string 'load average'. // Otherwise, the result contains "sudo: a password is required". // This may not work on all OSX versions because of a bug in sudo in its version 1.7.10, // therefore we keep the old behaviour of sending a 'dummy' password under OSX. // See : https://superuser.com/questions/902826/why-does-sudo-n-on-mac-os-x-always-return-0 // // If for some reason we are getting empty output from pipe, we revert to old behavior // We also use the old way if the user is forcing the use of dummy password for sudo #if defined(TC_LINUX ) || defined (TC_FREEBSD) bool authCheckDone = false; if (!Core->GetUseDummySudoPassword ()) { std::vector<char> buffer(128, 0); std::string result; - FILE* pipe = popen("sudo -n uptime 2>&1 | grep 'load average' | wc -l", "r"); // We redirect stderr to stdout (2>&1) to be able to catch the result of the command + FILE* pipe = popen("sudo -n uptime 2>&1 | grep 'load average' | wc -l | tr -d '[:blank:]'", "r"); // We redirect stderr to stdout (2>&1) to be able to catch the result of the command if (pipe) { while (!feof(pipe)) { if (fgets(buffer.data(), 128, pipe) != nullptr) result += buffer.data(); } fflush(pipe); pclose(pipe); pipe = NULL; if (!result.empty() && strlen(result.c_str()) != 0) { authCheckDone = true; if (result[0] == '0') // no line found with "load average" text, rerquest admin password (*AdminPasswordCallback) (request.AdminPassword); } } if (authCheckDone) { // Set to false to force the 'WarningEvent' to be raised in case of and elevation exception. request.FastElevation = false; } } #endif try { request.Serialize (ServiceInputStream); @@ -516,88 +516,88 @@ namespace VeraCrypt { // Prevent defunct process struct WaitFunctor : public Functor { WaitFunctor (int pid) : Pid (pid) { } virtual void operator() () { int status; for (int t = 0; t < 10 && waitpid (Pid, &status, WNOHANG) == 0; t++) Thread::Sleep (1000); } int Pid; }; Thread thread; thread.Start (new WaitFunctor (forkedPid)); throw ElevationFailed (SRC_POS, "sudo", 1, ""); } waitRes = waitpid (forkedPid, &status, 0); } } if (!errOutput.empty()) { unique_ptr <Serializable> deserializedObject; Exception *deserializedException = nullptr; try { - shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((byte *) &errOutput[0], errOutput.size()))); + shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((uint8 *) &errOutput[0], errOutput.size()))); deserializedObject.reset (Serializable::DeserializeNew (stream)); deserializedException = dynamic_cast <Exception*> (deserializedObject.get()); } catch (...) { } if (deserializedException) deserializedException->Throw(); } throw_sys_if (waitRes == -1); exitCode = (WIFEXITED (status) ? WEXITSTATUS (status) : 1); if (exitCode != 0) { string strErrOutput; if (!errOutput.empty()) strErrOutput.insert (strErrOutput.begin(), errOutput.begin(), errOutput.end()); // sudo may require a tty even if -S is used if (strErrOutput.find (" tty") != string::npos) strErrOutput += "\nTo enable use of 'sudo' by applications without a terminal window, please disable 'requiretty' option in '/etc/sudoers'. Newer versions of sudo automatically determine whether a terminal is required ('requiretty' option is obsolete)."; throw ElevationFailed (SRC_POS, "sudo", exitCode, strErrOutput); } throw_sys_if (fcntl (outPipe->GetReadFD(), F_SETFL, 0) == -1); ServiceInputStream = shared_ptr <Stream> (new FileStream (inPipe->GetWriteFD())); ServiceOutputStream = shared_ptr <Stream> (new FileStream (outPipe->GetReadFD())); // Send sync code - byte sync[] = { 0, 0x11, 0x22 }; + uint8 sync[] = { 0, 0x11, 0x22 }; ServiceInputStream->Write (ConstBufferPtr (sync, array_capacity (sync))); AdminInputPipe = move_ptr(inPipe); AdminOutputPipe = move_ptr(outPipe); } void CoreService::Stop () { ExitRequest exitRequest; exitRequest.Serialize (ServiceInputStream); } shared_ptr <GetStringFunctor> CoreService::AdminPasswordCallback; unique_ptr <Pipe> CoreService::AdminInputPipe; unique_ptr <Pipe> CoreService::AdminOutputPipe; unique_ptr <Pipe> CoreService::InputPipe; unique_ptr <Pipe> CoreService::OutputPipe; shared_ptr <Stream> CoreService::ServiceInputStream; shared_ptr <Stream> CoreService::ServiceOutputStream; bool CoreService::ElevatedPrivileges = false; bool CoreService::ElevatedServiceAvailable = false; } diff --git a/src/Core/Unix/CoreUnix.cpp b/src/Core/Unix/CoreUnix.cpp index 0b248fb9..1868eb6d 100644 --- a/src/Core/Unix/CoreUnix.cpp +++ b/src/Core/Unix/CoreUnix.cpp @@ -1,57 +1,54 @@ /* Derived from source code of TrueCrypt 7.1a, which is Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #include "CoreUnix.h" #include <errno.h> #include <iostream> #include <signal.h> #include <sys/stat.h> #include <sys/types.h> #include <stdio.h> #include <unistd.h> #include "Platform/FileStream.h" #include "Driver/Fuse/FuseService.h" #include "Volume/VolumePasswordCache.h" -template<typename T> -inline void ignore_result(const T & /* unused result */) {} - namespace VeraCrypt { #ifdef TC_LINUX static string GetTmpUser (); static bool SamePath (const string& path1, const string& path2); #endif CoreUnix::CoreUnix () { signal (SIGPIPE, SIG_IGN); char *loc = setlocale (LC_ALL, ""); if (!loc || string (loc) == "C") setlocale (LC_ALL, "en_US.UTF-8"); } CoreUnix::~CoreUnix () { } void CoreUnix::CheckFilesystem (shared_ptr <VolumeInfo> mountedVolume, bool repair) const { if (!mountedVolume->MountPoint.IsEmpty()) DismountFilesystem (mountedVolume->MountPoint, false); list <string> args; args.push_back ("-T"); args.push_back ("fsck"); @@ -217,61 +214,61 @@ namespace VeraCrypt || fs.Type == "fatfs" || fs.Type == "msdos" || fs.Type == "msdosfs" || fs.Type == "umsdos" || fs.Type == "dos" || fs.Type == "dosfs" || fs.Type == "pcfs" ) { return false; } return true; } } catch (...) { } } return true; // Prevent errors if the filesystem cannot be identified } bool CoreUnix::FilesystemSupportsUnixPermissions (const DevicePath &devicePath) const { File device; device.Open (devicePath); Buffer bootSector (device.GetDeviceSectorSize()); device.SeekAt (0); device.ReadCompleteBuffer (bootSector); - byte *b = bootSector.Ptr(); + uint8 *b = bootSector.Ptr(); return memcmp (b + 3, "NTFS", 4) != 0 && memcmp (b + 54, "FAT", 3) != 0 && memcmp (b + 82, "FAT32", 5) != 0 && memcmp (b + 3, "EXFAT", 5) != 0; } string CoreUnix::GetDefaultMountPointPrefix () const { const char *envPrefix = getenv ("VERACRYPT_MOUNT_PREFIX"); if (envPrefix && !string (envPrefix).empty()) return envPrefix; if (FilesystemPath ("/media").IsDirectory()) return "/media/veracrypt"; if (FilesystemPath ("/mnt").IsDirectory()) return "/mnt/veracrypt"; return GetTempDirectory() + "/veracrypt_mnt"; } uint32 CoreUnix::GetDeviceSectorSize (const DevicePath &devicePath) const { File dev; dev.Open (devicePath); return dev.GetDeviceSectorSize(); } uint64 CoreUnix::GetDeviceSize (const DevicePath &devicePath) const @@ -279,71 +276,99 @@ namespace VeraCrypt File dev; dev.Open (devicePath); return dev.Length(); } DirectoryPath CoreUnix::GetDeviceMountPoint (const DevicePath &devicePath) const { DevicePath devPath = devicePath; #ifdef TC_MACOSX if (string (devPath).find ("/dev/rdisk") != string::npos) devPath = string ("/dev/") + string (devicePath).substr (6); #endif MountedFilesystemList mountedFilesystems = GetMountedFilesystems (devPath); if (mountedFilesystems.size() < 1) return DirectoryPath(); return mountedFilesystems.front()->MountPoint; } VolumeInfoList CoreUnix::GetMountedVolumes (const VolumePath &volumePath) const { VolumeInfoList volumes; foreach_ref (const MountedFilesystem &mf, GetMountedFilesystems ()) { if (string (mf.MountPoint).find (GetFuseMountDirPrefix()) == string::npos) continue; shared_ptr <VolumeInfo> mountedVol; - try + // Introduce a retry mechanism with a timeout for control file access + // This workaround is limited to FUSE-T mounted volume under macOS for + // which md.Device starts with "fuse-t:" +#ifdef VC_MACOSX_FUSET + bool isFuseT = wstring(mf.Device).find(L"fuse-t:") == 0; + int controlFileRetries = 10; // 10 retries with 500ms sleep each, total 5 seconds + while (!mountedVol && (controlFileRetries-- > 0)) +#endif { - shared_ptr <File> controlFile (new File); - controlFile->Open (string (mf.MountPoint) + FuseService::GetControlPath()); + try + { + shared_ptr <File> controlFile (new File); + controlFile->Open (string (mf.MountPoint) + FuseService::GetControlPath()); - shared_ptr <Stream> controlFileStream (new FileStream (controlFile)); - mountedVol = Serializable::DeserializeNew <VolumeInfo> (controlFileStream); + shared_ptr <Stream> controlFileStream (new FileStream (controlFile)); + mountedVol = Serializable::DeserializeNew <VolumeInfo> (controlFileStream); + } + catch (const std::exception& e) + { +#ifdef VC_MACOSX_FUSET + // if exception starts with "VeraCrypt::Serializer::ValidateName", then + // serialization is not ready yet and we need to wait before retrying + // this happens when FUSE-T is used under macOS and if it is the first time + // the volume is mounted + if (isFuseT && string (e.what()).find ("VeraCrypt::Serializer::ValidateName") != string::npos) + { + Thread::Sleep(500); // Wait before retrying + } + else + { + break; // Control file not found or other error + } +#endif + } } - catch (...) + + if (!mountedVol) { - continue; + continue; // Skip to the next mounted filesystem } if (!volumePath.IsEmpty() && wstring (mountedVol->Path).compare (volumePath) != 0) continue; mountedVol->AuxMountPoint = mf.MountPoint; if (!mountedVol->VirtualDevice.IsEmpty()) { MountedFilesystemList mpl = GetMountedFilesystems (mountedVol->VirtualDevice); if (mpl.size() > 0) mountedVol->MountPoint = mpl.front()->MountPoint; } volumes.push_back (mountedVol); if (!volumePath.IsEmpty()) break; } return volumes; } gid_t CoreUnix::GetRealGroupId () const { const char *env = getenv ("SUDO_GID"); if (env) { try @@ -667,61 +692,61 @@ namespace VeraCrypt } try { try { MountVolumeNative (volume, options, fuseMountPoint); } catch (NotApplicable&) { MountAuxVolumeImage (fuseMountPoint, options); } } catch (...) { if (mountDirCreated) remove (mountPoint.c_str()); throw; } #ifndef TC_MACOSX // set again correct ownership of the mount point to avoid any issues if (!options.NoFilesystem && options.MountPoint) { mountPoint = *options.MountPoint; if (mountPoint.find (GetDefaultMountPointPrefix()) == 0) { try { - ignore_result(chown (mountPoint.c_str(), GetRealUserId(), GetRealGroupId())); + throw_sys_sub_if (chown (mountPoint.c_str(), GetRealUserId(), GetRealGroupId()) == -1, mountPoint); } catch (...) { } } } #endif } catch (...) { try { VolumeInfoList mountedVolumes = GetMountedVolumes (*options.Path); if (mountedVolumes.size() > 0) { shared_ptr <VolumeInfo> mountedVolume (mountedVolumes.front()); DismountVolume (mountedVolume); } } catch (...) { } throw; } VolumeInfoList mountedVolumes = GetMountedVolumes (*options.Path); if (mountedVolumes.size() != 1) throw ParameterIncorrect (SRC_POS); VolumeEventArgs eventArgs (mountedVolumes.front()); VolumeMountedEvent.Raise (eventArgs); return mountedVolumes.front(); } diff --git a/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp b/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp index 01463c35..05520274 100644 --- a/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp +++ b/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp @@ -56,61 +56,61 @@ namespace VeraCrypt void CoreFreeBSD::DetachLoopDevice (const DevicePath &devicePath) const { list <string> args; args.push_back ("-d"); args.push_back ("-u"); args.push_back (StringConverter::GetTrailingNumber (devicePath)); for (int t = 0; true; t++) { try { Process::Execute ("mdconfig", args); break; } catch (ExecutedProcessFailed&) { if (t > 5) throw; Thread::Sleep (200); } } } HostDeviceList CoreFreeBSD::GetHostDevices (bool pathListOnly) const { HostDeviceList devices; #ifdef TC_MACOSX const string busType = "rdisk"; #else - foreach (const string &busType, StringConverter::Split ("ad da")) + foreach (const string &busType, StringConverter::Split ("ad da vtbd")) #endif { for (int devNumber = 0; devNumber < 64; devNumber++) { stringstream devPath; devPath << "/dev/" << busType << devNumber; if (FilesystemPath (devPath.str()).IsBlockDevice() || FilesystemPath (devPath.str()).IsCharacterDevice()) { make_shared_auto (HostDevice, device); device->Path = devPath.str(); if (!pathListOnly) { try { device->Size = GetDeviceSize (device->Path); } catch (...) { device->Size = 0; } device->MountPoint = GetDeviceMountPoint (device->Path); device->SystemNumber = 0; } devices.push_back (device); for (int partNumber = 1; partNumber < 32; partNumber++) { #ifdef TC_MACOSX const string partLetter = ""; @@ -158,49 +158,90 @@ namespace VeraCrypt struct statfs *sysMountList; int count = getmntinfo (&sysMountList, MNT_NOWAIT); throw_sys_if (count == 0); MountedFilesystemList mountedFilesystems; for (int i = 0; i < count; i++) { make_shared_auto (MountedFilesystem, mf); if (sysMountList[i].f_mntfromname[0]) mf->Device = DevicePath (sysMountList[i].f_mntfromname); else continue; if (sysMountList[i].f_mntonname[0]) mf->MountPoint = DirectoryPath (sysMountList[i].f_mntonname); mf->Type = sysMountList[i].f_fstypename; if ((devicePath.IsEmpty() || devicePath == mf->Device) && (mountPoint.IsEmpty() || mountPoint == mf->MountPoint)) mountedFilesystems.push_back (mf); } return mountedFilesystems; } void CoreFreeBSD::MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const { + std::string chosenFilesystem = "msdos"; + std::string modifiedMountOptions = systemMountOptions; + + if (filesystemType.empty() && modifiedMountOptions.find("mountprog") == string::npos) { + // No filesystem type specified through CLI, attempt to identify with blkid + // as mount is unable to probe filesystem type on BSD + // Make sure we don't override user defined mountprog + std::vector<char> buffer(128,0); + std::string cmd = "blkid -o value -s TYPE " + static_cast<std::string>(devicePath) + " 2>/dev/null"; + std::string result; + + FILE* pipe = popen(cmd.c_str(), "r"); + if (pipe) { + while (!feof(pipe)) { + if (fgets(buffer.data(), 128, pipe) != nullptr) + result += buffer.data(); + } + fflush(pipe); + pclose(pipe); + pipe = nullptr; + } + + if (result.find("ext") == 0 || StringConverter::ToLower(filesystemType).find("ext") == 0) { + chosenFilesystem = "ext2fs"; + } + else if (result.find("exfat") == 0 || StringConverter::ToLower(filesystemType) == "exfat") { + chosenFilesystem = "exfat"; + modifiedMountOptions += string(!systemMountOptions.empty() ? "," : "") + + "mountprog=/usr/local/sbin/mount.exfat"; + } + else if (result.find("ntfs") == 0 || StringConverter::ToLower(filesystemType) == "ntfs") { + chosenFilesystem = "ntfs"; + modifiedMountOptions += string(!systemMountOptions.empty() ? "," : "") + + "mountprog=/usr/local/bin/ntfs-3g"; + } + else if (!filesystemType.empty()) { + // Filesystem is specified but is none of the above, then supply as is + chosenFilesystem = filesystemType; + } + } else + chosenFilesystem = filesystemType; + try { - // Try to mount FAT by default as mount is unable to probe filesystem type on BSD - CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType.empty() ? "msdos" : filesystemType, readOnly, systemMountOptions); + CoreUnix::MountFilesystem (devicePath, mountPoint, chosenFilesystem, readOnly, modifiedMountOptions); } catch (ExecutedProcessFailed&) { if (!filesystemType.empty()) throw; CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType, readOnly, systemMountOptions); } } #ifdef TC_FREEBSD unique_ptr <CoreBase> Core (new CoreServiceProxy <CoreFreeBSD>); unique_ptr <CoreBase> CoreDirect (new CoreFreeBSD); #endif } diff --git a/src/Core/Unix/Linux/CoreLinux.cpp b/src/Core/Unix/Linux/CoreLinux.cpp index e1da6dff..cd4be80f 100644 --- a/src/Core/Unix/Linux/CoreLinux.cpp +++ b/src/Core/Unix/Linux/CoreLinux.cpp @@ -1,54 +1,57 @@ /* Derived from source code of TrueCrypt 7.1a, which is Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #include <fstream> #include <iomanip> #include <mntent.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/mount.h> #include <sys/wait.h> #include "CoreLinux.h" #include "Platform/SystemInfo.h" #include "Platform/TextReader.h" #include "Volume/EncryptionModeXTS.h" +#ifdef WOLFCRYPT_BACKEND +#include "Volume/EncryptionModeWolfCryptXTS.h" +#endif #include "Driver/Fuse/FuseService.h" #include "Core/Unix/CoreServiceProxy.h" namespace VeraCrypt { CoreLinux::CoreLinux () { } CoreLinux::~CoreLinux () { } DevicePath CoreLinux::AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const { list <string> loopPaths; loopPaths.push_back ("/dev/loop"); loopPaths.push_back ("/dev/loop/"); loopPaths.push_back ("/dev/.static/dev/loop"); // On Fedora 23,"losetup -f" must be called first to create a default loop device list <string> args; args.push_back ("-f"); try { Process::Execute ("losetup", args); } catch (...) { } @@ -275,62 +278,67 @@ namespace VeraCrypt if ((devicePath.IsEmpty() || devicePath == mf->Device || realDevicePath == mf->Device) && (mountPoint.IsEmpty() || mountPoint == mf->MountPoint)) mountedFilesystems.push_back (mf); } return mountedFilesystems; } void CoreLinux::MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const { bool fsMounted = false; try { if (!FilesystemSupportsUnixPermissions (devicePath)) { stringstream userMountOptions; userMountOptions << "uid=" << GetRealUserId() << ",gid=" << GetRealGroupId() << ",umask=077" << (!systemMountOptions.empty() ? "," : ""); CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType, readOnly, userMountOptions.str() + systemMountOptions); fsMounted = true; } } catch (...) { } if (!fsMounted) CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType, readOnly, systemMountOptions); } void CoreLinux::MountVolumeNative (shared_ptr <Volume> volume, MountOptions &options, const DirectoryPath &auxMountPoint) const { - bool xts = (typeid (*volume->GetEncryptionMode()) == typeid (EncryptionModeXTS)); - bool algoNotSupported = (typeid (*volume->GetEncryptionAlgorithm()) == typeid (Kuznyechik)) + bool xts = (typeid (*volume->GetEncryptionMode()) == + #ifdef WOLFCRYPT_BACKEND + typeid (EncryptionModeWolfCryptXTS)); + #else + typeid (EncryptionModeXTS)); + #endif + bool algoNotSupported = (typeid (*volume->GetEncryptionAlgorithm()) == typeid (Kuznyechik)) || (typeid (*volume->GetEncryptionAlgorithm()) == typeid (CamelliaKuznyechik)) || (typeid (*volume->GetEncryptionAlgorithm()) == typeid (KuznyechikTwofish)) || (typeid (*volume->GetEncryptionAlgorithm()) == typeid (KuznyechikAES)) || (typeid (*volume->GetEncryptionAlgorithm()) == typeid (KuznyechikSerpentCamellia)); if (options.NoKernelCrypto || !xts || algoNotSupported || volume->IsEncryptionNotCompleted () || volume->GetProtectionType() == VolumeProtection::HiddenVolumeReadOnly) { throw NotApplicable (SRC_POS); } if (!SystemInfo::IsVersionAtLeast (2, 6, xts ? 24 : 20)) throw NotApplicable (SRC_POS); // Load device mapper kernel module list <string> execArgs; foreach (const string &dmModule, StringConverter::Split ("dm_mod dm-mod dm")) { execArgs.clear(); execArgs.push_back (dmModule); try { Process::Execute ("modprobe", execArgs); break; } catch (...) { } @@ -351,61 +359,61 @@ namespace VeraCrypt string nativeDevPath; try { // Create virtual device using device mapper size_t nativeDevCount = 0; size_t secondaryKeyOffset = volume->GetEncryptionMode()->GetKey().Size(); size_t cipherCount = volume->GetEncryptionAlgorithm()->GetCiphers().size(); foreach_reverse_ref (const Cipher &cipher, volume->GetEncryptionAlgorithm()->GetCiphers()) { stringstream dmCreateArgs; dmCreateArgs << "0 " << volume->GetSize() / ENCRYPTION_DATA_UNIT_SIZE << " crypt "; // Mode dmCreateArgs << StringConverter::ToLower (StringConverter::ToSingle (cipher.GetName())) << (xts ? (SystemInfo::IsVersionAtLeast (2, 6, 33) ? "-xts-plain64 " : "-xts-plain ") : "-lrw-benbi "); size_t keyArgOffset = dmCreateArgs.str().size(); dmCreateArgs << setw (cipher.GetKeySize() * (xts ? 4 : 2) + (xts ? 0 : 16 * 2)) << 0 << setw (0); // Sector and data unit offset uint64 startSector = volume->GetLayout()->GetDataOffset (volume->GetHostSize()) / ENCRYPTION_DATA_UNIT_SIZE; dmCreateArgs << ' ' << (xts ? startSector + volume->GetEncryptionMode()->GetSectorOffset() : 0) << ' '; if (nativeDevCount == 0) dmCreateArgs << string (volumePath) << ' ' << startSector; else dmCreateArgs << nativeDevPath << " 0"; SecureBuffer dmCreateArgsBuf (dmCreateArgs.str().size()); - dmCreateArgsBuf.CopyFrom (ConstBufferPtr ((byte *) dmCreateArgs.str().c_str(), dmCreateArgs.str().size())); + dmCreateArgsBuf.CopyFrom (ConstBufferPtr ((uint8 *) dmCreateArgs.str().c_str(), dmCreateArgs.str().size())); // Keys const SecureBuffer &cipherKey = cipher.GetKey(); secondaryKeyOffset -= cipherKey.Size(); ConstBufferPtr secondaryKey = volume->GetEncryptionMode()->GetKey().GetRange (xts ? secondaryKeyOffset : 0, xts ? cipherKey.Size() : 16); SecureBuffer hexStr (3); for (size_t i = 0; i < cipherKey.Size(); ++i) { sprintf ((char *) hexStr.Ptr(), "%02x", (int) cipherKey[i]); dmCreateArgsBuf.GetRange (keyArgOffset + i * 2, 2).CopyFrom (hexStr.GetRange (0, 2)); sprintf ((char *) hexStr.Ptr(), "%02x", (int) secondaryKey[i]); dmCreateArgsBuf.GetRange (keyArgOffset + cipherKey.Size() * 2 + i * 2, 2).CopyFrom (hexStr.GetRange (0, 2)); } stringstream nativeDevName; nativeDevName << "veracrypt" << options.SlotNumber; if (nativeDevCount != cipherCount - 1) nativeDevName << "_" << cipherCount - nativeDevCount - 2; nativeDevPath = "/dev/mapper/" + nativeDevName.str(); execArgs.clear(); execArgs.push_back ("create"); execArgs.push_back (nativeDevName.str()); Process::Execute ("dmsetup", execArgs, -1, nullptr, &dmCreateArgsBuf); diff --git a/src/Core/Unix/MacOSX/CoreMacOSX.cpp b/src/Core/Unix/MacOSX/CoreMacOSX.cpp index b596e6e8..cfd34072 100644 --- a/src/Core/Unix/MacOSX/CoreMacOSX.cpp +++ b/src/Core/Unix/MacOSX/CoreMacOSX.cpp @@ -80,101 +80,108 @@ namespace VeraCrypt args.push_back ("--"); args.push_back (mountedVolume->AuxMountPoint); for (int t = 0; true; t++) { try { Process::Execute ("umount", args); break; } catch (ExecutedProcessFailed&) { if (t > 10) throw; Thread::Sleep (200); } } try { mountedVolume->AuxMountPoint.Delete(); } catch (...) { } return mountedVolume; } void CoreMacOSX::CheckFilesystem (shared_ptr <VolumeInfo> mountedVolume, bool repair) const { list <string> args; - args.push_back ("/Applications/Utilities/Disk Utility.app"); + struct stat sb; + + if (stat("/Applications/Utilities/Disk Utility.app", &sb) == 0) + args.push_back ("/Applications/Utilities/Disk Utility.app"); + else + args.push_back ("/System/Applications/Utilities/Disk Utility.app"); + Process::Execute ("open", args); } void CoreMacOSX::MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const { +#ifndef VC_MACOSX_FUSET // Check FUSE version char fuseVersionString[MAXHOSTNAMELEN + 1] = { 0 }; size_t fuseVersionStringLength = MAXHOSTNAMELEN; int status; if ((status = sysctlbyname ("osxfuse.version.number", fuseVersionString, &fuseVersionStringLength, NULL, 0)) != 0) { fuseVersionStringLength = MAXHOSTNAMELEN; if ((status = sysctlbyname ("vfs.generic.osxfuse.version.number", fuseVersionString, &fuseVersionStringLength, NULL, 0)) != 0) { fuseVersionStringLength = MAXHOSTNAMELEN; if ((status = sysctlbyname ("vfs.generic.macfuse.version.number", fuseVersionString, &fuseVersionStringLength, NULL, 0)) != 0) { throw HigherFuseVersionRequired (SRC_POS); } } } // look for OSXFuse dynamic library struct stat sb; if (0 != stat("/usr/local/lib/libosxfuse_i64.2.dylib", &sb) && 0 != stat("/usr/local/lib/libfuse.dylib", &sb)) { throw HigherFuseVersionRequired (SRC_POS); } vector <string> fuseVersion = StringConverter::Split (string (fuseVersionString), "."); if (fuseVersion.size() < 2) throw HigherFuseVersionRequired (SRC_POS); uint32 fuseVersionMajor = StringConverter::ToUInt32 (fuseVersion[0]); uint32 fuseVersionMinor = StringConverter::ToUInt32 (fuseVersion[1]); if (fuseVersionMajor < 2 || (fuseVersionMajor == 2 && fuseVersionMinor < 5)) throw HigherFuseVersionRequired (SRC_POS); - +#endif // Mount volume image string volImage = string (auxMountPoint) + FuseService::GetVolumeImagePath(); list <string> args; args.push_back ("attach"); args.push_back (volImage); args.push_back ("-plist"); args.push_back ("-noautofsck"); args.push_back ("-imagekey"); args.push_back ("diskimage-class=CRawDiskImage"); if (!options.NoFilesystem && options.MountPoint && !options.MountPoint->IsEmpty()) { args.push_back ("-mount"); args.push_back ("required"); // Let the system specify mount point except when the user specified a non-default one if (string (*options.MountPoint).find (GetDefaultMountPointPrefix()) != 0) { args.push_back ("-mountpoint"); args.push_back (*options.MountPoint); } } else args.push_back ("-nomount"); if (options.Protection == VolumeProtection::ReadOnly) args.push_back ("-readonly"); string xml; |