diff --git a/src/Core/Unix/CoreService.cpp b/src/Core/Unix/CoreService.cpp index fd7bc577..ae7381ff 100644 --- a/src/Core/Unix/CoreService.cpp +++ b/src/Core/Unix/CoreService.cpp @@ -914,6 +914,168 @@ namespace VeraCrypt } #endif +#ifdef TC_OPENBSD + static bool ParseOpenBSDVndDevicePath (const string &path, bool rawDevice, string &deviceNumber) + { + const string prefix = rawDevice ? "/dev/rvnd" : "/dev/vnd"; + if (path.find (prefix) != 0) + return false; + + size_t numberStart = prefix.size(); + size_t numberEnd = numberStart; + while (numberEnd < path.size() && path[numberEnd] >= '0' && path[numberEnd] <= '9') + ++numberEnd; + + if (numberEnd == numberStart) + return false; + + if (numberEnd + 1 != path.size() || path[numberEnd] != 'c') + return false; + + deviceNumber = path.substr (numberStart, numberEnd - numberStart); + return true; + } + + static string GetOpenBSDVndBlockDevicePath (const DevicePath &rawDevice) + { + string deviceNumber; + if (!ParseOpenBSDVndDevicePath (string (rawDevice), true, deviceNumber)) + throw ParameterIncorrect (SRC_POS); + + return string ("/dev/vnd") + deviceNumber + "c"; + } + + static void ValidateOpenBSDVndDeviceNode (const string &path, bool rawDevice) + { + string deviceNumber; + if (!ParseOpenBSDVndDevicePath (path, rawDevice, deviceNumber)) + throw ParameterIncorrect (SRC_POS); + + struct stat sb; + if (lstat (path.c_str(), &sb) != 0) + throw ParameterIncorrect (SRC_POS); + + if (rawDevice) + { + if (!S_ISCHR (sb.st_mode)) + throw ParameterIncorrect (SRC_POS); + } + else if (!S_ISBLK (sb.st_mode)) + throw ParameterIncorrect (SRC_POS); + } + + static void ValidateOpenBSDFFSFormatterRequest (const ExecuteOpenBSDFFSFormatterRequest &request) + { + ValidateOpenBSDVndDeviceNode (string (request.Device), true); + ValidateOpenBSDVndDeviceNode (GetOpenBSDVndBlockDevicePath (request.Device), false); + + if (request.OwnerUserId > static_cast ((uid_t) -1) + || request.OwnerGroupId > static_cast ((gid_t) -1)) + { + throw ParameterIncorrect (SRC_POS); + } + } + + static list BuildOpenBSDFFSFormatterArguments (const ExecuteOpenBSDFFSFormatterRequest &request) + { + ValidateOpenBSDFFSFormatterRequest (request); + + list arguments; + arguments.push_back (string (request.Device)); + return arguments; + } + + static DirectoryPath CreateOpenBSDFFSTemporaryMountPoint () + { + string mountPointTemplate = "/tmp/veracrypt-ffs.XXXXXXXXXX"; + vector mountPoint (mountPointTemplate.begin(), mountPointTemplate.end()); + mountPoint.push_back ('\0'); + + char *createdPath = mkdtemp (&mountPoint.front()); + throw_sys_sub_if (!createdPath, mountPointTemplate); + + return DirectoryPath (createdPath); + } + + static void RemoveOpenBSDFFSTemporaryMountPoint (const DirectoryPath &mountPoint) + { + if (!mountPoint.IsEmpty()) + rmdir (string (mountPoint).c_str()); + } + + static void MountOpenBSDFFSTemporaryFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint) + { + list args; + args.push_back ("-t"); + args.push_back ("ffs"); + args.push_back ("-o"); + args.push_back ("nodev,nosuid,noexec"); + args.push_back ("--"); + args.push_back (devicePath); + args.push_back (mountPoint); + + Process::Execute ("mount", args); + } + + static void DismountOpenBSDFFSTemporaryFilesystem (const DirectoryPath &mountPoint) + { + list args; + args.push_back ("--"); + args.push_back (mountPoint); + + for (int attempt = 0; true; ++attempt) + { + try + { + Process::Execute ("umount", args); + return; + } + catch (ExecutedProcessFailed&) + { + if (attempt >= 5) + throw; + Thread::Sleep (200); + } + } + } + + static void SetOpenBSDFFSRootOwner (const ExecuteOpenBSDFFSFormatterRequest &request) + { + ValidateOpenBSDFFSFormatterRequest (request); + + DirectoryPath mountPoint = CreateOpenBSDFFSTemporaryMountPoint(); + bool mounted = false; + + try + { + MountOpenBSDFFSTemporaryFilesystem (DevicePath (GetOpenBSDVndBlockDevicePath (request.Device)), mountPoint); + mounted = true; + + string mountPointStr = mountPoint; + throw_sys_sub_if (chown (mountPointStr.c_str(), static_cast (request.OwnerUserId), static_cast (request.OwnerGroupId)) == -1, mountPointStr); + + DismountOpenBSDFFSTemporaryFilesystem (mountPoint); + mounted = false; + + throw_sys_sub_if (rmdir (mountPointStr.c_str()) == -1, mountPointStr); + } + catch (...) + { + if (mounted) + { + try + { + DismountOpenBSDFFSTemporaryFilesystem (mountPoint); + } + catch (...) { } + } + + RemoveOpenBSDFFSTemporaryMountPoint (mountPoint); + throw; + } + } +#endif + unique_ptr CoreService::GetResponseObject () { unique_ptr deserializedObject (Serializable::DeserializeNew (ServiceOutputStream)); @@ -1131,6 +1293,18 @@ namespace VeraCrypt } #endif +#ifdef TC_OPENBSD + // ExecuteOpenBSDFFSFormatterRequest + ExecuteOpenBSDFFSFormatterRequest *executeFFSFormatterRequest = dynamic_cast (request.get()); + if (executeFFSFormatterRequest) + { + Process::Execute (CoreService::GetOpenBSDFFSFormatterPath(), BuildOpenBSDFFSFormatterArguments (*executeFFSFormatterRequest)); + SetOpenBSDFFSRootOwner (*executeFFSFormatterRequest); + ExecuteOpenBSDFFSFormatterResponse().Serialize (outputStream); + continue; + } +#endif + // MountVolumeRequest MountVolumeRequest *mountRequest = dynamic_cast (request.get()); if (mountRequest) @@ -1237,6 +1411,19 @@ namespace VeraCrypt } #endif +#ifdef TC_OPENBSD + const char *CoreService::GetOpenBSDFFSFormatterPath () + { + return "/sbin/newfs"; + } + + void CoreService::RequestExecuteOpenBSDFFSFormatter (const DevicePath &devicePath, uint64 userId, uint64 groupId) + { + ExecuteOpenBSDFFSFormatterRequest request (devicePath, userId, groupId); + SendRequest (request); + } +#endif + shared_ptr CoreService::RequestMountVolume (MountOptions &options) { MountVolumeRequest request (&options); diff --git a/src/Core/Unix/CoreService.h b/src/Core/Unix/CoreService.h index 1979a589..f11f259c 100644 --- a/src/Core/Unix/CoreService.h +++ b/src/Core/Unix/CoreService.h @@ -38,6 +38,10 @@ namespace VeraCrypt #ifdef TC_MACOSX static const char *GetMacOSXAPFSFormatterPath (); static void RequestExecuteMacOSXAPFSFormatter (const DevicePath &devicePath, uint64 userId, uint64 groupId); +#endif +#ifdef TC_OPENBSD + static const char *GetOpenBSDFFSFormatterPath (); + static void RequestExecuteOpenBSDFFSFormatter (const DevicePath &devicePath, uint64 userId, uint64 groupId); #endif static shared_ptr RequestMountVolume (MountOptions &options); static void RequestSetFileOwner (const FilesystemPath &path, const UserId &owner); diff --git a/src/Core/Unix/CoreServiceRequest.cpp b/src/Core/Unix/CoreServiceRequest.cpp index 84fdfd5c..e9fcc112 100644 --- a/src/Core/Unix/CoreServiceRequest.cpp +++ b/src/Core/Unix/CoreServiceRequest.cpp @@ -245,6 +245,32 @@ namespace VeraCrypt } #endif +#ifdef TC_OPENBSD + // ExecuteOpenBSDFFSFormatterRequest + void ExecuteOpenBSDFFSFormatterRequest::Deserialize (shared_ptr stream) + { + CoreServiceRequest::Deserialize (stream); + Serializer sr (stream); + Device = sr.DeserializeWString ("Device"); + sr.Deserialize ("OwnerGroupId", OwnerGroupId); + sr.Deserialize ("OwnerUserId", OwnerUserId); + } + + bool ExecuteOpenBSDFFSFormatterRequest::RequiresElevation () const + { + return !Core->HasAdminPrivileges(); + } + + void ExecuteOpenBSDFFSFormatterRequest::Serialize (shared_ptr 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) { @@ -322,6 +348,9 @@ namespace VeraCrypt TC_SERIALIZER_FACTORY_ADD_CLASS (ExitRequest); #ifdef TC_MACOSX TC_SERIALIZER_FACTORY_ADD_CLASS (ExecuteMacOSXAPFSFormatterRequest); +#endif +#ifdef TC_OPENBSD + TC_SERIALIZER_FACTORY_ADD_CLASS (ExecuteOpenBSDFFSFormatterRequest); #endif TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSectorSizeRequest); TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSizeRequest); diff --git a/src/Core/Unix/CoreServiceRequest.h b/src/Core/Unix/CoreServiceRequest.h index 7222ea32..10e4eeb4 100644 --- a/src/Core/Unix/CoreServiceRequest.h +++ b/src/Core/Unix/CoreServiceRequest.h @@ -142,6 +142,22 @@ namespace VeraCrypt }; #endif +#ifdef TC_OPENBSD + struct ExecuteOpenBSDFFSFormatterRequest : CoreServiceRequest + { + ExecuteOpenBSDFFSFormatterRequest () { } + ExecuteOpenBSDFFSFormatterRequest (const DevicePath &devicePath, uint64 userId, uint64 groupId) + : Device (devicePath), OwnerGroupId (groupId), OwnerUserId (userId) { } + TC_SERIALIZABLE (ExecuteOpenBSDFFSFormatterRequest); + + virtual bool RequiresElevation () const; + + DevicePath Device; + uint64 OwnerGroupId; + uint64 OwnerUserId; + }; +#endif + struct MountVolumeRequest : CoreServiceRequest { MountVolumeRequest () { } diff --git a/src/Core/Unix/CoreServiceResponse.cpp b/src/Core/Unix/CoreServiceResponse.cpp index e14eea2b..0209635d 100644 --- a/src/Core/Unix/CoreServiceResponse.cpp +++ b/src/Core/Unix/CoreServiceResponse.cpp @@ -110,6 +110,18 @@ namespace VeraCrypt } #endif +#ifdef TC_OPENBSD + // ExecuteOpenBSDFFSFormatterResponse + void ExecuteOpenBSDFFSFormatterResponse::Deserialize (shared_ptr stream) + { + } + + void ExecuteOpenBSDFFSFormatterResponse::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + } +#endif + // MountVolumeResponse void MountVolumeResponse::Deserialize (shared_ptr stream) { @@ -143,6 +155,9 @@ namespace VeraCrypt TC_SERIALIZER_FACTORY_ADD_CLASS (GetHostDevicesResponse); #ifdef TC_MACOSX TC_SERIALIZER_FACTORY_ADD_CLASS (ExecuteMacOSXAPFSFormatterResponse); +#endif +#ifdef TC_OPENBSD + TC_SERIALIZER_FACTORY_ADD_CLASS (ExecuteOpenBSDFFSFormatterResponse); #endif TC_SERIALIZER_FACTORY_ADD_CLASS (MountVolumeResponse); TC_SERIALIZER_FACTORY_ADD_CLASS (SetFileOwnerResponse); diff --git a/src/Core/Unix/CoreServiceResponse.h b/src/Core/Unix/CoreServiceResponse.h index d6c318ba..61c7d31f 100644 --- a/src/Core/Unix/CoreServiceResponse.h +++ b/src/Core/Unix/CoreServiceResponse.h @@ -83,6 +83,14 @@ namespace VeraCrypt }; #endif +#ifdef TC_OPENBSD + struct ExecuteOpenBSDFFSFormatterResponse : CoreServiceResponse + { + ExecuteOpenBSDFFSFormatterResponse () { } + TC_SERIALIZABLE (ExecuteOpenBSDFFSFormatterResponse); + }; +#endif + struct MountVolumeResponse : CoreServiceResponse { MountVolumeResponse () { } diff --git a/src/Core/VolumeCreator.h b/src/Core/VolumeCreator.h index 0e842556..78862a72 100644 --- a/src/Core/VolumeCreator.h +++ b/src/Core/VolumeCreator.h @@ -55,7 +55,8 @@ namespace VeraCrypt Btrfs, MacOsExt, APFS, - UFS + UFS, + FFS }; static Enum GetPlatformNative () @@ -68,6 +69,8 @@ namespace VeraCrypt return VolumeCreationOptions::FilesystemType::MacOsExt; #elif defined (TC_FREEBSD) || defined (TC_SOLARIS) return VolumeCreationOptions::FilesystemType::UFS; +#elif defined (TC_OPENBSD) + return VolumeCreationOptions::FilesystemType::FFS; #else return VolumeCreationOptions::FilesystemType::FAT; #endif @@ -90,6 +93,8 @@ namespace VeraCrypt case VolumeCreationOptions::FilesystemType::APFS: return "newfs_apfs"; #elif defined (TC_FREEBSD) || defined (TC_SOLARIS) case VolumeCreationOptions::FilesystemType::UFS: return "newfs" ; + #elif defined (TC_OPENBSD) + case VolumeCreationOptions::FilesystemType::FFS: return "newfs" ; #endif default: return NULL; } diff --git a/src/Main/CommandLineInterface.cpp b/src/Main/CommandLineInterface.cpp index 754146b7..17b9b940 100644 --- a/src/Main/CommandLineInterface.cpp +++ b/src/Main/CommandLineInterface.cpp @@ -415,6 +415,12 @@ namespace VeraCrypt ArgFilesystem = VolumeCreationOptions::FilesystemType::NTFS; else if (str.IsSameAs (L"exFAT", false)) ArgFilesystem = VolumeCreationOptions::FilesystemType::exFAT; +#elif defined (TC_OPENBSD) + else if (str.IsSameAs (L"FFS", false) || str.IsSameAs (L"UFS", false)) + { + ArgMountOptions.FilesystemType = L"ffs"; + ArgFilesystem = VolumeCreationOptions::FilesystemType::FFS; + } #endif else throw_err (LangString["UNKNOWN_OPTION"] + L": " + str); diff --git a/src/Main/Forms/VolumeCreationWizard.cpp b/src/Main/Forms/VolumeCreationWizard.cpp index 730d3306..6fdbf418 100644 --- a/src/Main/Forms/VolumeCreationWizard.cpp +++ b/src/Main/Forms/VolumeCreationWizard.cpp @@ -25,6 +25,9 @@ #ifdef TC_MACOSX #include "Main/MacOSXFormatterDevice.h" #endif +#ifdef TC_OPENBSD +#include "Main/OpenBSDFormatterDevice.h" +#endif #include "Main/Resources.h" #include "VolumeCreationWizard.h" #include "EncryptionOptionsWizardPage.h" @@ -857,9 +860,11 @@ namespace VeraCrypt // Temporarily take ownership of the device if the user is not an administrator DevicePath virtualDevice = volume->VirtualDevice; + DevicePath formatterDevice = virtualDevice; #ifdef TC_MACOSX string virtualDeviceStr = virtualDevice; virtualDevice = GetMacOSXRawDevicePath (virtualDeviceStr); + formatterDevice = virtualDevice; MacOSXFormatterDeviceOwnerRestoreList changedDeviceOwners; finally_do_arg (MacOSXFormatterDeviceOwnerRestoreList *, &changedDeviceOwners, @@ -868,25 +873,37 @@ namespace VeraCrypt }); bool useElevatedAPFSFormatter = UseElevatedMacOSXAPFSFormatter (fsFormatter); if (!useElevatedAPFSFormatter) - PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners); + PrepareMacOSXFormatterDevice (formatterDevice, changedDeviceOwners); #else +#ifdef TC_OPENBSD + if (SelectedFilesystemType == VolumeCreationOptions::FilesystemType::FFS) + formatterDevice = GetOpenBSDRawFormatterDevicePath (virtualDevice); +#endif + bool prepareFormatterDeviceOwnership = true; +#ifdef TC_OPENBSD + if (SelectedFilesystemType == VolumeCreationOptions::FilesystemType::FFS) + prepareFormatterDeviceOwnership = false; +#endif UserId origDeviceOwner ((uid_t) -1); - try + if (prepareFormatterDeviceOwnership) { - File file; - file.Open (virtualDevice, File::OpenReadWrite); - } - catch (...) - { - if (!Core->HasAdminPrivileges()) + try { - origDeviceOwner = virtualDevice.GetOwner(); - Core->SetFileOwner (virtualDevice, UserId (getuid())); + File file; + file.Open (formatterDevice, File::OpenReadWrite); + } + catch (...) + { + if (!Core->HasAdminPrivileges()) + { + origDeviceOwner = formatterDevice.GetOwner(); + Core->SetFileOwner (formatterDevice, UserId (getuid())); + } } } - finally_do_arg2 (FilesystemPath, virtualDevice, UserId, origDeviceOwner, + finally_do_arg2 (FilesystemPath, formatterDevice, UserId, origDeviceOwner, { if (finally_arg2.SystemId != (uid_t) -1) Core->SetFileOwner (finally_arg, finally_arg2); @@ -921,11 +938,13 @@ namespace VeraCrypt AddMacOSXAPFSFormatterUserArgs (args); #endif - args.push_back (string (virtualDevice)); + args.push_back (string (formatterDevice)); SetCreationProgressText (StringFormatter (LangString["FORMAT_STAGE_CREATING_FILESYSTEM"], fsFormatter)); #ifdef TC_MACOSX ExecuteMacOSXFilesystemFormatter (fsFormatter, args); +#elif defined (TC_OPENBSD) + ExecuteOpenBSDFilesystemFormatter (fsFormatter, args); #else Process::Execute (fsFormatter, args); #endif diff --git a/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp b/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp index 1c78a56e..d3506030 100644 --- a/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp +++ b/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp @@ -52,6 +52,8 @@ namespace VeraCrypt FilesystemTypeChoice->Append (L"APFS", (void *) VolumeCreationOptions::FilesystemType::APFS); #elif defined (TC_FREEBSD) || defined (TC_SOLARIS) FilesystemTypeChoice->Append (L"UFS", (void *) VolumeCreationOptions::FilesystemType::UFS); +#elif defined (TC_OPENBSD) + FilesystemTypeChoice->Append (L"FFS", (void *) VolumeCreationOptions::FilesystemType::FFS); #endif if (!disable32bitFilesystems && filesystemSize <= TC_MAX_FAT_SECTOR_COUNT * sectorSize) @@ -94,6 +96,7 @@ namespace VeraCrypt case VolumeCreationOptions::FilesystemType::MacOsExt: FilesystemTypeChoice->SetStringSelection (L"Mac OS Extended"); break; case VolumeCreationOptions::FilesystemType::APFS: FilesystemTypeChoice->SetStringSelection (L"APFS"); break; case VolumeCreationOptions::FilesystemType::UFS: FilesystemTypeChoice->SetStringSelection (L"UFS"); break; + case VolumeCreationOptions::FilesystemType::FFS: FilesystemTypeChoice->SetStringSelection (L"FFS"); break; default: throw ParameterIncorrect (SRC_POS); diff --git a/src/Main/OpenBSDFormatterDevice.h b/src/Main/OpenBSDFormatterDevice.h new file mode 100644 index 00000000..250e836b --- /dev/null +++ b/src/Main/OpenBSDFormatterDevice.h @@ -0,0 +1,123 @@ +/* + VeraCrypt source code + Copyright (c) 2026 AM Crypto + + This file is part of VeraCrypt and is 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. +*/ + +#ifndef TC_HEADER_Main_OpenBSDFormatterDevice +#define TC_HEADER_Main_OpenBSDFormatterDevice + +#include "Main/Main.h" + +#ifdef TC_OPENBSD +#include +#include +#include +#include "Core/Unix/CoreService.h" +#include "Core/Unix/UnixUser.h" +#include "Platform/Unix/Process.h" + +namespace VeraCrypt +{ + inline bool IsOpenBSDVndDevicePath (const string &path, bool rawDevice) + { + const string prefix = rawDevice ? "/dev/rvnd" : "/dev/vnd"; + if (path.find (prefix) != 0) + return false; + + size_t numberStart = prefix.size(); + size_t numberEnd = numberStart; + while (numberEnd < path.size() && path[numberEnd] >= '0' && path[numberEnd] <= '9') + ++numberEnd; + + return numberEnd > numberStart + && numberEnd + 1 == path.size() + && path[numberEnd] == 'c'; + } + + inline DevicePath GetOpenBSDRawFormatterDevicePath (const DevicePath &path) + { + string pathStr = path; + + if (IsOpenBSDVndDevicePath (pathStr, true)) + return path; + + if (IsOpenBSDVndDevicePath (pathStr, false)) + return DevicePath (string ("/dev/r") + pathStr.substr (5)); + + return path; + } + + inline string GetOpenBSDFormatterName (const string &fsFormatter) + { + size_t namePos = fsFormatter.find_last_of ('/'); + return namePos == string::npos ? fsFormatter : fsFormatter.substr (namePos + 1); + } + + inline bool IsOpenBSDFFSFormatter (const string &fsFormatter) + { + return GetOpenBSDFormatterName (fsFormatter) == "newfs"; + } + + inline bool GetOpenBSDFormatterEnvId (const char *name, uint64 &id) + { + const char *env = getenv (name); + if (!env || !env[0]) + return false; + + char *endPtr = nullptr; + errno = 0; + unsigned long long value = strtoull (env, &endPtr, 10); + if (errno != 0 || !endPtr || *endPtr != '\0') + return false; + + id = static_cast (value); + return true; + } + + inline uint64 GetOpenBSDFormatterOwnerUserId () + { + uint64 id; + if (GetOpenBSDFormatterEnvId ("SUDO_UID", id)) + return id; + + uid_t doasUid; + if (GetDoasUserIds (&doasUid, nullptr)) + return static_cast (doasUid); + + return static_cast (getuid()); + } + + inline uint64 GetOpenBSDFormatterOwnerGroupId () + { + uint64 id; + if (GetOpenBSDFormatterEnvId ("SUDO_GID", id)) + return id; + + gid_t doasGid; + if (GetDoasUserIds (nullptr, &doasGid)) + return static_cast (doasGid); + + return static_cast (getgid()); + } + + inline void ExecuteOpenBSDFilesystemFormatter (const string &fsFormatter, const list &args) + { + if (IsOpenBSDFFSFormatter (fsFormatter)) + { + if (args.empty()) + throw ParameterIncorrect (SRC_POS); + + CoreService::RequestExecuteOpenBSDFFSFormatter (DevicePath (args.back()), GetOpenBSDFormatterOwnerUserId(), GetOpenBSDFormatterOwnerGroupId()); + return; + } + + Process::Execute (fsFormatter, args); + } +} +#endif // TC_OPENBSD + +#endif // TC_HEADER_Main_OpenBSDFormatterDevice diff --git a/src/Main/TextUserInterface.cpp b/src/Main/TextUserInterface.cpp index e99c8474..aba0aa15 100644 --- a/src/Main/TextUserInterface.cpp +++ b/src/Main/TextUserInterface.cpp @@ -29,6 +29,9 @@ #ifdef TC_MACOSX #include "Main/MacOSXFormatterDevice.h" #endif +#ifdef TC_OPENBSD +#include "Main/OpenBSDFormatterDevice.h" +#endif #include "TextUserInterface.h" namespace VeraCrypt @@ -933,7 +936,13 @@ namespace VeraCrypt { if (Preferences.NonInteractive) { +#ifdef TC_OPENBSD + // Preserve the historical OpenBSD batch default. Native FFS + // formatting requires elevation, so scripts should opt in. + options->Filesystem = VolumeCreationOptions::FilesystemType::FAT; +#else options->Filesystem = VolumeCreationOptions::FilesystemType::GetPlatformNative(); +#endif } else { @@ -974,6 +983,8 @@ namespace VeraCrypt } #elif defined (TC_FREEBSD) || defined (TC_SOLARIS) ShowInfo (wxString::Format (L" %li) %s", filesystems.size() + 1, "UFS")); filesystems.push_back (VolumeCreationOptions::FilesystemType::UFS); +#elif defined (TC_OPENBSD) + ShowInfo (wxString::Format (L" %li) %s", filesystems.size() + 1, "FFS")); filesystems.push_back (VolumeCreationOptions::FilesystemType::FFS); #endif ssize_t defaultFilesystem = fatAvailable ? 2 : 1; @@ -1123,9 +1134,11 @@ namespace VeraCrypt // Temporarily take ownership of the device if the user is not an administrator DevicePath virtualDevice = volume->VirtualDevice; + DevicePath formatterDevice = virtualDevice; #ifdef TC_MACOSX string virtualDeviceStr = virtualDevice; virtualDevice = GetMacOSXRawDevicePath (virtualDeviceStr); + formatterDevice = virtualDevice; MacOSXFormatterDeviceOwnerRestoreList changedDeviceOwners; finally_do_arg (MacOSXFormatterDeviceOwnerRestoreList *, &changedDeviceOwners, @@ -1134,25 +1147,37 @@ namespace VeraCrypt }); bool useElevatedAPFSFormatter = UseElevatedMacOSXAPFSFormatter (fsFormatter); if (!useElevatedAPFSFormatter) - PrepareMacOSXFormatterDevice (virtualDevice, changedDeviceOwners); + PrepareMacOSXFormatterDevice (formatterDevice, changedDeviceOwners); #else +#ifdef TC_OPENBSD + if (options->Filesystem == VolumeCreationOptions::FilesystemType::FFS) + formatterDevice = GetOpenBSDRawFormatterDevicePath (virtualDevice); +#endif + bool prepareFormatterDeviceOwnership = true; +#ifdef TC_OPENBSD + if (options->Filesystem == VolumeCreationOptions::FilesystemType::FFS) + prepareFormatterDeviceOwnership = false; +#endif UserId origDeviceOwner ((uid_t) -1); - try + if (prepareFormatterDeviceOwnership) { - File file; - file.Open (virtualDevice, File::OpenReadWrite); - } - catch (...) - { - if (!Core->HasAdminPrivileges()) + try { - origDeviceOwner = virtualDevice.GetOwner(); - Core->SetFileOwner (virtualDevice, UserId (getuid())); + File file; + file.Open (formatterDevice, File::OpenReadWrite); + } + catch (...) + { + if (!Core->HasAdminPrivileges()) + { + origDeviceOwner = formatterDevice.GetOwner(); + Core->SetFileOwner (formatterDevice, UserId (getuid())); + } } } - finally_do_arg2 (FilesystemPath, virtualDevice, UserId, origDeviceOwner, + finally_do_arg2 (FilesystemPath, formatterDevice, UserId, origDeviceOwner, { if (finally_arg2.SystemId != (uid_t) -1) Core->SetFileOwner (finally_arg, finally_arg2); @@ -1187,10 +1212,12 @@ namespace VeraCrypt AddMacOSXAPFSFormatterUserArgs (args); #endif - args.push_back (string (virtualDevice)); + args.push_back (string (formatterDevice)); #ifdef TC_MACOSX ExecuteMacOSXFilesystemFormatter (fsFormatter, args); +#elif defined (TC_OPENBSD) + ExecuteOpenBSDFilesystemFormatter (fsFormatter, args); #else Process::Execute (fsFormatter, args); #endif diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp index 665a7941..57ec848f 100644 --- a/src/Main/UserInterface.cpp +++ b/src/Main/UserInterface.cpp @@ -1373,6 +1373,10 @@ const FileManager fileManagers[] = { " with option -t. Default type is 'auto'. When creating a new volume, this\n" " option specifies the filesystem to be created on the new volume.\n" " Filesystem type 'none' disables mounting or creating a filesystem.\n" +#ifdef TC_OPENBSD + " On OpenBSD, filesystem type 'FFS' creates a native FFS volume and\n" + " mounts with filesystem type 'ffs'.\n" +#endif #ifdef TC_LINUX " On Linux, filesystem type 'ntfs3' mounts with the in-kernel ntfs3\n" " driver and bypasses mount helpers. Filesystem type 'kernel-ntfs'\n"