1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-12-29 10:09:43 -06:00

Add TrueCrypt 7.1a MacOSX/Linux specific source files.

This commit is contained in:
Mounir IDRASSI
2014-05-31 18:44:53 +02:00
parent 97011f179c
commit 7ffce028d0
203 changed files with 52120 additions and 0 deletions

View File

@@ -0,0 +1,544 @@
/*
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include "CoreService.h"
#include <fcntl.h>
#include <sys/wait.h>
#include "Platform/FileStream.h"
#include "Platform/MemoryStream.h"
#include "Platform/Serializable.h"
#include "Platform/SystemLog.h"
#include "Platform/Thread.h"
#include "Platform/Unix/Poller.h"
#include "Core/Core.h"
#include "CoreUnix.h"
#include "CoreServiceRequest.h"
#include "CoreServiceResponse.h"
namespace TrueCrypt
{
template <class T>
auto_ptr <T> CoreService::GetResponse ()
{
auto_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 auto_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;
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)
{
try
{
Core = CoreDirect;
shared_ptr <Stream> inputStream (new FileStream (inputFD != -1 ? inputFD : InputPipe->GetReadFD()));
shared_ptr <Stream> outputStream (new FileStream (outputFD != -1 ? outputFD : OutputPipe->GetWriteFD()));
while (true)
{
shared_ptr <CoreServiceRequest> request = Serializable::DeserializeNew <CoreServiceRequest> (inputStream);
try
{
// ExitRequest
if (dynamic_cast <ExitRequest*> (request.get()) != nullptr)
{
if (ElevatedServiceAvailable)
request->Serialize (ServiceInputStream);
return;
}
if (!ElevatedPrivileges && request->ElevateUserPrivileges)
{
if (!ElevatedServiceAvailable)
{
finally_do_arg (string *, &request->AdminPassword, { StringConverter::Erase (*finally_arg); });
CoreService::StartElevated (*request);
ElevatedServiceAvailable = true;
}
request->Serialize (ServiceInputStream);
GetResponse <Serializable>()->Serialize (outputStream);
continue;
}
// CheckFilesystemRequest
CheckFilesystemRequest *checkRequest = dynamic_cast <CheckFilesystemRequest*> (request.get());
if (checkRequest)
{
Core->CheckFilesystem (checkRequest->MountedVolumeInfo, checkRequest->Repair);
CheckFilesystemResponse().Serialize (outputStream);
continue;
}
// DismountFilesystemRequest
DismountFilesystemRequest *dismountFsRequest = dynamic_cast <DismountFilesystemRequest*> (request.get());
if (dismountFsRequest)
{
Core->DismountFilesystem (dismountFsRequest->MountPoint, dismountFsRequest->Force);
DismountFilesystemResponse().Serialize (outputStream);
continue;
}
// DismountVolumeRequest
DismountVolumeRequest *dismountRequest = dynamic_cast <DismountVolumeRequest*> (request.get());
if (dismountRequest)
{
DismountVolumeResponse response;
response.DismountedVolumeInfo = Core->DismountVolume (dismountRequest->MountedVolumeInfo, dismountRequest->IgnoreOpenFiles, dismountRequest->SyncVolumeInfo);
response.Serialize (outputStream);
continue;
}
// GetDeviceSectorSizeRequest
GetDeviceSectorSizeRequest *getDeviceSectorSizeRequest = dynamic_cast <GetDeviceSectorSizeRequest*> (request.get());
if (getDeviceSectorSizeRequest)
{
GetDeviceSectorSizeResponse response;
response.Size = Core->GetDeviceSectorSize (getDeviceSectorSizeRequest->Path);
response.Serialize (outputStream);
continue;
}
// GetDeviceSizeRequest
GetDeviceSizeRequest *getDeviceSizeRequest = dynamic_cast <GetDeviceSizeRequest*> (request.get());
if (getDeviceSizeRequest)
{
GetDeviceSizeResponse response;
response.Size = Core->GetDeviceSize (getDeviceSizeRequest->Path);
response.Serialize (outputStream);
continue;
}
// GetHostDevicesRequest
GetHostDevicesRequest *getHostDevicesRequest = dynamic_cast <GetHostDevicesRequest*> (request.get());
if (getHostDevicesRequest)
{
GetHostDevicesResponse response;
response.HostDevices = Core->GetHostDevices (getHostDevicesRequest->PathListOnly);
response.Serialize (outputStream);
continue;
}
// MountVolumeRequest
MountVolumeRequest *mountRequest = dynamic_cast <MountVolumeRequest*> (request.get());
if (mountRequest)
{
MountVolumeResponse (
Core->MountVolume (*mountRequest->Options)
).Serialize (outputStream);
continue;
}
// SetFileOwnerRequest
SetFileOwnerRequest *setFileOwnerRequest = dynamic_cast <SetFileOwnerRequest*> (request.get());
if (setFileOwnerRequest)
{
CoreUnix *coreUnix = dynamic_cast <CoreUnix *> (Core.get());
if (!coreUnix)
throw ParameterIncorrect (SRC_POS);
coreUnix->SetFileOwner (setFileOwnerRequest->Path, setFileOwnerRequest->Owner);
SetFileOwnerResponse().Serialize (outputStream);
continue;
}
throw ParameterIncorrect (SRC_POS);
}
catch (Exception &e)
{
e.Serialize (outputStream);
}
catch (exception &e)
{
ExternalException (SRC_POS, StringConverter::ToExceptionString (e)).Serialize (outputStream);
}
}
}
catch (exception &e)
{
#ifdef DEBUG
SystemLog::WriteException (e);
#endif
throw;
}
}
void CoreService::RequestCheckFilesystem (shared_ptr <VolumeInfo> mountedVolume, bool repair)
{
CheckFilesystemRequest request (mountedVolume, repair);
SendRequest <CheckFilesystemResponse> (request);
}
void CoreService::RequestDismountFilesystem (const DirectoryPath &mountPoint, bool force)
{
DismountFilesystemRequest request (mountPoint, force);
SendRequest <DismountFilesystemResponse> (request);
}
shared_ptr <VolumeInfo> CoreService::RequestDismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo)
{
DismountVolumeRequest request (mountedVolume, ignoreOpenFiles, syncVolumeInfo);
return SendRequest <DismountVolumeResponse> (request)->DismountedVolumeInfo;
}
uint32 CoreService::RequestGetDeviceSectorSize (const DevicePath &devicePath)
{
GetDeviceSectorSizeRequest request (devicePath);
return SendRequest <GetDeviceSectorSizeResponse> (request)->Size;
}
uint64 CoreService::RequestGetDeviceSize (const DevicePath &devicePath)
{
GetDeviceSizeRequest request (devicePath);
return SendRequest <GetDeviceSizeResponse> (request)->Size;
}
HostDeviceList CoreService::RequestGetHostDevices (bool pathListOnly)
{
GetHostDevicesRequest request (pathListOnly);
return SendRequest <GetHostDevicesResponse> (request)->HostDevices;
}
shared_ptr <VolumeInfo> CoreService::RequestMountVolume (MountOptions &options)
{
MountVolumeRequest request (&options);
return SendRequest <MountVolumeResponse> (request)->MountedVolumeInfo;
}
void CoreService::RequestSetFileOwner (const FilesystemPath &path, const UserId &owner)
{
SetFileOwnerRequest request (path, owner);
SendRequest <SetFileOwnerResponse> (request);
}
template <class T>
auto_ptr <T> CoreService::SendRequest (CoreServiceRequest &request)
{
static Mutex mutex;
ScopeLock lock (mutex);
if (request.RequiresElevation())
{
request.ElevateUserPrivileges = true;
request.FastElevation = !ElevatedServiceAvailable;
request.ApplicationExecutablePath = Core->GetApplicationExecutablePath();
while (!ElevatedServiceAvailable)
{
try
{
request.Serialize (ServiceInputStream);
auto_ptr <T> response (GetResponse <T>());
ElevatedServiceAvailable = true;
return response;
}
catch (ElevationFailed &e)
{
if (!request.FastElevation)
{
ExceptionEventArgs args (e);
Core->WarningEvent.Raise (args);
}
request.FastElevation = false;
(*AdminPasswordCallback) (request.AdminPassword);
}
}
}
finally_do_arg (string *, &request.AdminPassword, { StringConverter::Erase (*finally_arg); });
request.Serialize (ServiceInputStream);
return GetResponse <T>();
}
void CoreService::Start ()
{
InputPipe.reset (new Pipe());
OutputPipe.reset (new Pipe());
int pid = fork();
throw_sys_if (pid == -1);
if (pid == 0)
{
try
{
ProcessRequests();
_exit (0);
}
catch (...) { }
_exit (1);
}
ServiceInputStream = shared_ptr <Stream> (new FileStream (InputPipe->GetWriteFD()));
ServiceOutputStream = shared_ptr <Stream> (new FileStream (OutputPipe->GetReadFD()));
}
void CoreService::StartElevated (const CoreServiceRequest &request)
{
auto_ptr <Pipe> inPipe (new Pipe());
auto_ptr <Pipe> outPipe (new Pipe());
Pipe errPipe;
int forkedPid = fork();
throw_sys_if (forkedPid == -1);
if (forkedPid == 0)
{
try
{
try
{
throw_sys_if (dup2 (inPipe->GetReadFD(), STDIN_FILENO) == -1);
throw_sys_if (dup2 (outPipe->GetWriteFD(), STDOUT_FILENO) == -1);
throw_sys_if (dup2 (errPipe.GetWriteFD(), STDERR_FILENO) == -1);
string appPath = request.ApplicationExecutablePath;
if (appPath.empty())
appPath = "truecrypt";
const char *args[] = { "sudo", "-S", "-p", "", appPath.c_str(), TC_CORE_SERVICE_CMDLINE_OPTION, nullptr };
execvp (args[0], ((char* const*) args));
throw SystemException (SRC_POS, args[0]);
}
catch (Exception &)
{
throw;
}
catch (exception &e)
{
throw ExternalException (SRC_POS, StringConverter::ToExceptionString (e));
}
catch (...)
{
throw UnknownException (SRC_POS);
}
}
catch (Exception &e)
{
try
{
shared_ptr <Stream> outputStream (new FileStream (errPipe.GetWriteFD()));
e.Serialize (outputStream);
}
catch (...) { }
}
_exit (1);
}
vector <char> adminPassword (request.AdminPassword.size() + 1);
int timeout = 6000;
if (request.FastElevation)
{
string dummyPassword = "dummy\n";
adminPassword = vector <char> (dummyPassword.size());
Memory::Copy (&adminPassword.front(), dummyPassword.c_str(), dummyPassword.size());
timeout = 1000;
}
else
{
Memory::Copy (&adminPassword.front(), request.AdminPassword.c_str(), request.AdminPassword.size());
adminPassword[request.AdminPassword.size()] = '\n';
}
if (write (inPipe->GetWriteFD(), &adminPassword.front(), adminPassword.size())) { } // Errors ignored
Memory::Erase (&adminPassword.front(), adminPassword.size());
throw_sys_if (fcntl (outPipe->GetReadFD(), F_SETFL, O_NONBLOCK) == -1);
throw_sys_if (fcntl (errPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1);
vector <char> buffer (4096), errOutput (4096);
buffer.clear ();
errOutput.clear ();
Poller poller (outPipe->GetReadFD(), errPipe.GetReadFD());
int status, waitRes;
int exitCode = 1;
try
{
do
{
ssize_t bytesRead = 0;
foreach (int fd, poller.WaitForData (timeout))
{
bytesRead = read (fd, &buffer[0], buffer.capacity());
if (bytesRead > 0 && fd == errPipe.GetReadFD())
{
errOutput.insert (errOutput.end(), buffer.begin(), buffer.begin() + bytesRead);
if (bytesRead > 5 && bytesRead < 80) // Short message captured
timeout = 200;
}
}
if (bytesRead == 0)
{
waitRes = waitpid (forkedPid, &status, 0);
break;
}
} while ((waitRes = waitpid (forkedPid, &status, WNOHANG)) == 0);
}
catch (TimeOut&)
{
if ((waitRes = waitpid (forkedPid, &status, WNOHANG)) == 0)
{
inPipe->Close();
outPipe->Close();
errPipe.Close();
if (request.FastElevation)
{
// 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())
{
auto_ptr <Serializable> deserializedObject;
Exception *deserializedException = nullptr;
try
{
shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((byte *) &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 };
ServiceInputStream->Write (ConstBufferPtr (sync, array_capacity (sync)));
AdminInputPipe = inPipe;
AdminOutputPipe = outPipe;
}
void CoreService::Stop ()
{
ExitRequest exitRequest;
exitRequest.Serialize (ServiceInputStream);
}
shared_ptr <GetStringFunctor> CoreService::AdminPasswordCallback;
auto_ptr <Pipe> CoreService::AdminInputPipe;
auto_ptr <Pipe> CoreService::AdminOutputPipe;
auto_ptr <Pipe> CoreService::InputPipe;
auto_ptr <Pipe> CoreService::OutputPipe;
shared_ptr <Stream> CoreService::ServiceInputStream;
shared_ptr <Stream> CoreService::ServiceOutputStream;
bool CoreService::ElevatedPrivileges = false;
bool CoreService::ElevatedServiceAvailable = false;
}

View File

@@ -0,0 +1,63 @@
/*
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Core_Unix_CoreService
#define TC_HEADER_Core_Unix_CoreService
#include "CoreServiceRequest.h"
#include "Platform/Stream.h"
#include "Platform/Unix/Pipe.h"
#include "Core/Core.h"
namespace TrueCrypt
{
// This service facilitates process forking and elevation of user privileges
class CoreService
{
public:
static void ProcessElevatedRequests ();
static void ProcessRequests (int inputFD = -1, int outputFD = -1);
static void RequestCheckFilesystem (shared_ptr <VolumeInfo> mountedVolume, bool repair);
static void RequestDismountFilesystem (const DirectoryPath &mountPoint, bool force);
static shared_ptr <VolumeInfo> RequestDismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles = false, bool syncVolumeInfo = false);
static uint32 RequestGetDeviceSectorSize (const DevicePath &devicePath);
static uint64 RequestGetDeviceSize (const DevicePath &devicePath);
static HostDeviceList RequestGetHostDevices (bool pathListOnly);
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; }
static void Start ();
static void Stop ();
protected:
template <class T> static auto_ptr <T> GetResponse ();
template <class T> static auto_ptr <T> SendRequest (CoreServiceRequest &request);
static void StartElevated (const CoreServiceRequest &request);
static shared_ptr <GetStringFunctor> AdminPasswordCallback;
static auto_ptr <Pipe> AdminInputPipe;
static auto_ptr <Pipe> AdminOutputPipe;
static auto_ptr <Pipe> InputPipe;
static auto_ptr <Pipe> OutputPipe;
static shared_ptr <Stream> ServiceInputStream;
static shared_ptr <Stream> ServiceOutputStream;
static bool ElevatedPrivileges;
static bool ElevatedServiceAvailable;
static bool Running;
private:
CoreService ();
};
#define TC_CORE_SERVICE_CMDLINE_OPTION "--core-service"
}
#endif // TC_HEADER_Core_Unix_CoreService

View File

@@ -0,0 +1,152 @@
/*
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Core_Windows_CoreServiceProxy
#define TC_HEADER_Core_Windows_CoreServiceProxy
#include "CoreService.h"
#include "Volume/VolumePasswordCache.h"
namespace TrueCrypt
{
template <class T>
class CoreServiceProxy : public T
{
public:
CoreServiceProxy () { }
virtual ~CoreServiceProxy () { }
virtual void CheckFilesystem (shared_ptr <VolumeInfo> mountedVolume, bool repair) const
{
CoreService::RequestCheckFilesystem (mountedVolume, repair);
}
virtual void DismountFilesystem (const DirectoryPath &mountPoint, bool force) const
{
CoreService::RequestDismountFilesystem (mountPoint, force);
}
virtual shared_ptr <VolumeInfo> DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles = false, bool syncVolumeInfo = false)
{
shared_ptr <VolumeInfo> dismountedVolumeInfo = CoreService::RequestDismountVolume (mountedVolume, ignoreOpenFiles, syncVolumeInfo);
VolumeEventArgs eventArgs (dismountedVolumeInfo);
T::VolumeDismountedEvent.Raise (eventArgs);
return dismountedVolumeInfo;
}
virtual uint32 GetDeviceSectorSize (const DevicePath &devicePath) const
{
return CoreService::RequestGetDeviceSectorSize (devicePath);
}
virtual uint64 GetDeviceSize (const DevicePath &devicePath) const
{
return CoreService::RequestGetDeviceSize (devicePath);
}
#ifndef TC_LINUX
virtual HostDeviceList GetHostDevices (bool pathListOnly = false) const
{
if (pathListOnly)
return T::GetHostDevices (pathListOnly);
else
return CoreService::RequestGetHostDevices (pathListOnly);
}
#endif
virtual bool IsPasswordCacheEmpty () const { return VolumePasswordCache::IsEmpty(); }
virtual shared_ptr <VolumeInfo> MountVolume (MountOptions &options)
{
shared_ptr <VolumeInfo> mountedVolume;
if (!VolumePasswordCache::IsEmpty()
&& (!options.Password || options.Password->IsEmpty())
&& (!options.Keyfiles || options.Keyfiles->empty()))
{
finally_do_arg (MountOptions*, &options, { if (finally_arg->Password) finally_arg->Password.reset(); });
PasswordIncorrect passwordException;
foreach (shared_ptr <VolumePassword> password, VolumePasswordCache::GetPasswords())
{
try
{
options.Password = password;
mountedVolume = CoreService::RequestMountVolume (options);
break;
}
catch (PasswordIncorrect &e)
{
passwordException = e;
}
}
if (!mountedVolume)
passwordException.Throw();
}
else
{
MountOptions newOptions = options;
newOptions.Password = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password);
if (newOptions.Keyfiles)
newOptions.Keyfiles->clear();
newOptions.ProtectionPassword = Keyfile::ApplyListToPassword (options.ProtectionKeyfiles, options.ProtectionPassword);
if (newOptions.ProtectionKeyfiles)
newOptions.ProtectionKeyfiles->clear();
try
{
mountedVolume = CoreService::RequestMountVolume (newOptions);
}
catch (ProtectionPasswordIncorrect &e)
{
if (options.ProtectionKeyfiles && !options.ProtectionKeyfiles->empty())
throw ProtectionPasswordKeyfilesIncorrect (e.what());
throw;
}
catch (PasswordIncorrect &e)
{
if (options.Keyfiles && !options.Keyfiles->empty())
throw PasswordKeyfilesIncorrect (e.what());
throw;
}
if (options.CachePassword
&& ((options.Password && !options.Password->IsEmpty()) || (options.Keyfiles && !options.Keyfiles->empty())))
{
VolumePasswordCache::Store (*Keyfile::ApplyListToPassword (options.Keyfiles, options.Password));
}
}
VolumeEventArgs eventArgs (mountedVolume);
T::VolumeMountedEvent.Raise (eventArgs);
return mountedVolume;
}
virtual void SetAdminPasswordCallback (shared_ptr <GetStringFunctor> functor)
{
CoreService::SetAdminPasswordCallback (functor);
}
virtual void SetFileOwner (const FilesystemPath &path, const UserId &owner) const
{
CoreService::RequestSetFileOwner (path, owner);
}
virtual void WipePasswordCache () const
{
VolumePasswordCache::Clear();
}
};
}
#endif // TC_HEADER_Core_Windows_CoreServiceProxy

View File

@@ -0,0 +1,269 @@
/*
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <errno.h>
#include "CoreServiceRequest.h"
#include "Platform/SerializerFactory.h"
namespace TrueCrypt
{
void CoreServiceRequest::Deserialize (shared_ptr <Stream> stream)
{
Serializer sr (stream);
sr.Deserialize ("AdminPassword", AdminPassword);
ApplicationExecutablePath = sr.DeserializeWString ("ApplicationExecutablePath");
sr.Deserialize ("ElevateUserPrivileges", ElevateUserPrivileges);
sr.Deserialize ("FastElevation", FastElevation);
}
void CoreServiceRequest::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("AdminPassword", AdminPassword);
sr.Serialize ("ApplicationExecutablePath", wstring (ApplicationExecutablePath));
sr.Serialize ("ElevateUserPrivileges", ElevateUserPrivileges);
sr.Serialize ("FastElevation", FastElevation);
}
// CheckFilesystemRequest
void CheckFilesystemRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream);
sr.Deserialize ("Repair", Repair);
}
bool CheckFilesystemRequest::RequiresElevation () const
{
#ifdef TC_MACOSX
return false;
#endif
return !Core->HasAdminPrivileges();
}
void CheckFilesystemRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
MountedVolumeInfo->Serialize (stream);
sr.Serialize ("Repair", Repair);
}
// DismountFilesystemRequest
void DismountFilesystemRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
sr.Deserialize ("Force", Force);
MountPoint = sr.DeserializeWString ("MountPoint");
}
bool DismountFilesystemRequest::RequiresElevation () const
{
return !Core->HasAdminPrivileges();
}
void DismountFilesystemRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("Force", Force);
sr.Serialize ("MountPoint", wstring (MountPoint));
}
// DismountVolumeRequest
void DismountVolumeRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
sr.Deserialize ("IgnoreOpenFiles", IgnoreOpenFiles);
sr.Deserialize ("SyncVolumeInfo", SyncVolumeInfo);
MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream);
}
bool DismountVolumeRequest::RequiresElevation () const
{
#ifdef TC_MACOSX
if (MountedVolumeInfo->Path.IsDevice())
{
try
{
File file;
file.Open (MountedVolumeInfo->Path, File::OpenReadWrite);
}
catch (...)
{
return true;
}
}
return false;
#endif
return !Core->HasAdminPrivileges();
}
void DismountVolumeRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("IgnoreOpenFiles", IgnoreOpenFiles);
sr.Serialize ("SyncVolumeInfo", SyncVolumeInfo);
MountedVolumeInfo->Serialize (stream);
}
// GetDeviceSectorSizeRequest
void GetDeviceSectorSizeRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
Path = sr.DeserializeWString ("Path");
}
bool GetDeviceSectorSizeRequest::RequiresElevation () const
{
return !Core->HasAdminPrivileges();
}
void GetDeviceSectorSizeRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("Path", wstring (Path));
}
// GetDeviceSizeRequest
void GetDeviceSizeRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
Path = sr.DeserializeWString ("Path");
}
bool GetDeviceSizeRequest::RequiresElevation () const
{
return !Core->HasAdminPrivileges();
}
void GetDeviceSizeRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("Path", wstring (Path));
}
// GetHostDevicesRequest
void GetHostDevicesRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
sr.Deserialize ("PathListOnly", PathListOnly);
}
bool GetHostDevicesRequest::RequiresElevation () const
{
return !Core->HasAdminPrivileges();
}
void GetHostDevicesRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("PathListOnly", PathListOnly);
}
// ExitRequest
void ExitRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
}
void ExitRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
}
// MountVolumeRequest
void MountVolumeRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
DeserializedOptions = Serializable::DeserializeNew <MountOptions> (stream);
Options = DeserializedOptions.get();
}
bool MountVolumeRequest::RequiresElevation () const
{
#ifdef TC_MACOSX
if (Options->Path->IsDevice())
{
try
{
File file;
file.Open (*Options->Path, File::OpenReadWrite);
}
catch (...)
{
return true;
}
}
return false;
#endif
return !Core->HasAdminPrivileges();
}
void MountVolumeRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
Options->Serialize (stream);
}
// SetFileOwnerRequest
void SetFileOwnerRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
uint64 owner;
sr.Deserialize ("Owner", owner);
Owner.SystemId = static_cast <uid_t> (owner);
Path = sr.DeserializeWString ("Path");
}
bool SetFileOwnerRequest::RequiresElevation () const
{
return !Core->HasAdminPrivileges();
}
void SetFileOwnerRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
uint64 owner = Owner.SystemId;
sr.Serialize ("Owner", owner);
sr.Serialize ("Path", wstring (Path));
}
TC_SERIALIZER_FACTORY_ADD_CLASS (CoreServiceRequest);
TC_SERIALIZER_FACTORY_ADD_CLASS (CheckFilesystemRequest);
TC_SERIALIZER_FACTORY_ADD_CLASS (DismountFilesystemRequest);
TC_SERIALIZER_FACTORY_ADD_CLASS (DismountVolumeRequest);
TC_SERIALIZER_FACTORY_ADD_CLASS (ExitRequest);
TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSectorSizeRequest);
TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSizeRequest);
TC_SERIALIZER_FACTORY_ADD_CLASS (GetHostDevicesRequest);
TC_SERIALIZER_FACTORY_ADD_CLASS (MountVolumeRequest);
TC_SERIALIZER_FACTORY_ADD_CLASS (SetFileOwnerRequest);
}

View File

@@ -0,0 +1,136 @@
/*
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Core_Unix_CoreServiceRequest
#define TC_HEADER_Core_Unix_CoreServiceRequest
#include "Platform/Serializable.h"
#include "Core/Core.h"
namespace TrueCrypt
{
struct CoreServiceRequest : public Serializable
{
CoreServiceRequest () : ElevateUserPrivileges (false), FastElevation (false) { }
TC_SERIALIZABLE (CoreServiceRequest);
virtual bool RequiresElevation () const { return false; }
string AdminPassword;
FilePath ApplicationExecutablePath;
bool ElevateUserPrivileges;
bool FastElevation;
};
struct CheckFilesystemRequest : CoreServiceRequest
{
CheckFilesystemRequest () { }
CheckFilesystemRequest (shared_ptr <VolumeInfo> volumeInfo, bool repair)
: MountedVolumeInfo (volumeInfo), Repair (repair) { }
TC_SERIALIZABLE (CheckFilesystemRequest);
virtual bool RequiresElevation () const;
shared_ptr <VolumeInfo> MountedVolumeInfo;
bool Repair;
};
struct DismountFilesystemRequest : CoreServiceRequest
{
DismountFilesystemRequest () { }
DismountFilesystemRequest (const DirectoryPath &mountPoint, bool force)
: Force (force), MountPoint (mountPoint) { }
TC_SERIALIZABLE (DismountFilesystemRequest);
virtual bool RequiresElevation () const;
bool Force;
DirectoryPath MountPoint;
};
struct DismountVolumeRequest : CoreServiceRequest
{
DismountVolumeRequest () { }
DismountVolumeRequest (shared_ptr <VolumeInfo> volumeInfo, bool ignoreOpenFiles, bool syncVolumeInfo)
: IgnoreOpenFiles (ignoreOpenFiles), MountedVolumeInfo (volumeInfo), SyncVolumeInfo (syncVolumeInfo) { }
TC_SERIALIZABLE (DismountVolumeRequest);
virtual bool RequiresElevation () const;
bool IgnoreOpenFiles;
shared_ptr <VolumeInfo> MountedVolumeInfo;
bool SyncVolumeInfo;
};
struct GetDeviceSectorSizeRequest : CoreServiceRequest
{
GetDeviceSectorSizeRequest () { }
GetDeviceSectorSizeRequest (const DevicePath &path) : Path (path) { }
TC_SERIALIZABLE (GetDeviceSectorSizeRequest);
virtual bool RequiresElevation () const;
DevicePath Path;
};
struct GetDeviceSizeRequest : CoreServiceRequest
{
GetDeviceSizeRequest () { }
GetDeviceSizeRequest (const DevicePath &path) : Path (path) { }
TC_SERIALIZABLE (GetDeviceSizeRequest);
virtual bool RequiresElevation () const;
DevicePath Path;
};
struct GetHostDevicesRequest : CoreServiceRequest
{
GetHostDevicesRequest () { }
GetHostDevicesRequest (bool pathListOnly) : PathListOnly (pathListOnly) { }
TC_SERIALIZABLE (GetHostDevicesRequest);
virtual bool RequiresElevation () const;
bool PathListOnly;
};
struct ExitRequest : CoreServiceRequest
{
TC_SERIALIZABLE (ExitRequest);
};
struct MountVolumeRequest : CoreServiceRequest
{
MountVolumeRequest () { }
MountVolumeRequest (MountOptions *options) : Options (options) { }
TC_SERIALIZABLE (MountVolumeRequest);
virtual bool RequiresElevation () const;
MountOptions *Options;
protected:
shared_ptr <MountOptions> DeserializedOptions;
};
struct SetFileOwnerRequest : CoreServiceRequest
{
SetFileOwnerRequest () { }
SetFileOwnerRequest (const FilesystemPath &path, const UserId &owner) : Owner (owner), Path (path) { }
TC_SERIALIZABLE (SetFileOwnerRequest);
virtual bool RequiresElevation () const;
UserId Owner;
FilesystemPath Path;
};
}
#endif // TC_HEADER_Core_Unix_CoreServiceRequest

View File

@@ -0,0 +1,119 @@
/*
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include "CoreServiceResponse.h"
#include "Platform/SerializerFactory.h"
namespace TrueCrypt
{
// CheckFilesystemResponse
void CheckFilesystemResponse::Deserialize (shared_ptr <Stream> stream)
{
}
void CheckFilesystemResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
}
// DismountFilesystemResponse
void DismountFilesystemResponse::Deserialize (shared_ptr <Stream> stream)
{
}
void DismountFilesystemResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
}
// DismountVolumeResponse
void DismountVolumeResponse::Deserialize (shared_ptr <Stream> stream)
{
DismountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream);
}
void DismountVolumeResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
Serializer sr (stream);
DismountedVolumeInfo->Serialize (stream);
}
// GetDeviceSectorSizeResponse
void GetDeviceSectorSizeResponse::Deserialize (shared_ptr <Stream> stream)
{
Serializer sr (stream);
sr.Deserialize ("Size", Size);
}
void GetDeviceSectorSizeResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("Size", Size);
}
// GetDeviceSizeResponse
void GetDeviceSizeResponse::Deserialize (shared_ptr <Stream> stream)
{
Serializer sr (stream);
sr.Deserialize ("Size", Size);
}
void GetDeviceSizeResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("Size", Size);
}
// GetHostDevicesResponse
void GetHostDevicesResponse::Deserialize (shared_ptr <Stream> stream)
{
Serializable::DeserializeList (stream, HostDevices);
}
void GetHostDevicesResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
Serializable::SerializeList (stream, HostDevices);
}
// MountVolumeResponse
void MountVolumeResponse::Deserialize (shared_ptr <Stream> stream)
{
Serializer sr (stream);
MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream);
}
void MountVolumeResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
Serializer sr (stream);
MountedVolumeInfo->Serialize (stream);
}
// SetFileOwnerResponse
void SetFileOwnerResponse::Deserialize (shared_ptr <Stream> stream)
{
}
void SetFileOwnerResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
}
TC_SERIALIZER_FACTORY_ADD_CLASS (CheckFilesystemResponse);
TC_SERIALIZER_FACTORY_ADD_CLASS (DismountFilesystemResponse);
TC_SERIALIZER_FACTORY_ADD_CLASS (DismountVolumeResponse);
TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSectorSizeResponse);
TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSizeResponse);
TC_SERIALIZER_FACTORY_ADD_CLASS (GetHostDevicesResponse);
TC_SERIALIZER_FACTORY_ADD_CLASS (MountVolumeResponse);
TC_SERIALIZER_FACTORY_ADD_CLASS (SetFileOwnerResponse);
}

View File

@@ -0,0 +1,84 @@
/*
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Core_Unix_CoreServiceResponse
#define TC_HEADER_Core_Unix_CoreServiceResponse
#include "Platform/Serializable.h"
#include "Core/Core.h"
namespace TrueCrypt
{
struct CoreServiceResponse : public Serializable
{
};
struct CheckFilesystemResponse : CoreServiceResponse
{
CheckFilesystemResponse () { }
TC_SERIALIZABLE (CheckFilesystemResponse);
};
struct DismountFilesystemResponse : CoreServiceResponse
{
DismountFilesystemResponse () { }
TC_SERIALIZABLE (DismountFilesystemResponse);
};
struct DismountVolumeResponse : CoreServiceResponse
{
DismountVolumeResponse () { }
TC_SERIALIZABLE (DismountVolumeResponse);
shared_ptr <VolumeInfo> DismountedVolumeInfo;
};
struct GetDeviceSectorSizeResponse : CoreServiceResponse
{
GetDeviceSectorSizeResponse () { }
GetDeviceSectorSizeResponse (uint32 size) : Size (size) { }
TC_SERIALIZABLE (GetDeviceSectorSizeResponse);
uint32 Size;
};
struct GetDeviceSizeResponse : CoreServiceResponse
{
GetDeviceSizeResponse () { }
GetDeviceSizeResponse (uint64 size) : Size (size) { }
TC_SERIALIZABLE (GetDeviceSizeResponse);
uint64 Size;
};
struct GetHostDevicesResponse : CoreServiceResponse
{
GetHostDevicesResponse () { }
GetHostDevicesResponse (const HostDeviceList &hostDevices) : HostDevices (hostDevices) { }
TC_SERIALIZABLE (GetHostDevicesResponse);
HostDeviceList HostDevices;
};
struct MountVolumeResponse : CoreServiceResponse
{
MountVolumeResponse () { }
MountVolumeResponse (shared_ptr <VolumeInfo> volumeInfo) : MountedVolumeInfo (volumeInfo) { }
TC_SERIALIZABLE (MountVolumeResponse);
shared_ptr <VolumeInfo> MountedVolumeInfo;
};
struct SetFileOwnerResponse : CoreServiceResponse
{
SetFileOwnerResponse () { }
TC_SERIALIZABLE (SetFileOwnerResponse);
};
}
#endif // TC_HEADER_Core_Unix_CoreServiceResponse

618
src/Core/Unix/CoreUnix.cpp Normal file
View File

@@ -0,0 +1,618 @@
/*
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt 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"
namespace TrueCrypt
{
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");
args.push_back ("-e");
string xargs = "fsck ";
#ifdef TC_LINUX
if (!repair)
xargs += "-n ";
else
xargs += "-r ";
#endif
xargs += string (mountedVolume->VirtualDevice) + "; echo '[Done]'; read W";
args.push_back (xargs);
try
{
Process::Execute ("xterm", args, 1000);
} catch (TimeOut&) { }
}
void CoreUnix::DismountFilesystem (const DirectoryPath &mountPoint, bool force) const
{
list <string> args;
#ifdef TC_MACOSX
if (force)
args.push_back ("-f");
#endif
args.push_back ("--");
args.push_back (mountPoint);
Process::Execute ("umount", args);
}
shared_ptr <VolumeInfo> CoreUnix::DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo)
{
if (!mountedVolume->MountPoint.IsEmpty())
{
DismountFilesystem (mountedVolume->MountPoint, ignoreOpenFiles);
// Delete mount directory if a default path has been used
if (string (mountedVolume->MountPoint).find (GetDefaultMountPointPrefix()) == 0)
mountedVolume->MountPoint.Delete();
}
try
{
DismountNativeVolume (mountedVolume);
}
catch (NotApplicable &) { }
if (!mountedVolume->LoopDevice.IsEmpty())
{
try
{
DetachLoopDevice (mountedVolume->LoopDevice);
}
catch (ExecutedProcessFailed&) { }
}
if (syncVolumeInfo || mountedVolume->Protection == VolumeProtection::HiddenVolumeReadOnly)
{
sync();
VolumeInfoList ml = GetMountedVolumes (mountedVolume->Path);
if (ml.size() > 0)
mountedVolume = ml.front();
}
list <string> args;
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 (...) { }
VolumeEventArgs eventArgs (mountedVolume);
VolumeDismountedEvent.Raise (eventArgs);
return mountedVolume;
}
bool CoreUnix::FilesystemSupportsLargeFiles (const FilePath &filePath) const
{
string path = filePath;
size_t pos;
while ((pos = path.find_last_of ('/')) != string::npos)
{
path = path.substr (0, pos);
if (path.empty())
break;
try
{
MountedFilesystemList filesystems = GetMountedFilesystems (DevicePath(), path);
if (!filesystems.empty())
{
const MountedFilesystem &fs = *filesystems.front();
if (fs.Type == "fat"
|| fs.Type == "fat32"
|| fs.Type == "vfat"
|| 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();
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 ("TRUECRYPT_MOUNT_PREFIX");
if (envPrefix && !string (envPrefix).empty())
return envPrefix;
if (FilesystemPath ("/media").IsDirectory())
return "/media/truecrypt";
if (FilesystemPath ("/mnt").IsDirectory())
return "/mnt/truecrypt";
return GetTempDirectory() + "/truecrypt_mnt";
}
uint32 CoreUnix::GetDeviceSectorSize (const DevicePath &devicePath) const
{
File dev;
dev.Open (devicePath);
return dev.GetDeviceSectorSize();
}
uint64 CoreUnix::GetDeviceSize (const DevicePath &devicePath) const
{
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
{
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);
}
catch (...)
{
continue;
}
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
{
string s (env);
return static_cast <gid_t> (StringConverter::ToUInt64 (s));
}
catch (...) { }
}
return getgid();
}
uid_t CoreUnix::GetRealUserId () const
{
const char *env = getenv ("SUDO_UID");
if (env)
{
try
{
string s (env);
return static_cast <uid_t> (StringConverter::ToUInt64 (s));
}
catch (...) { }
}
return getuid();
}
string CoreUnix::GetTempDirectory () const
{
char *envDir = getenv ("TMPDIR");
return envDir ? envDir : "/tmp";
}
bool CoreUnix::IsMountPointAvailable (const DirectoryPath &mountPoint) const
{
return GetMountedFilesystems (DevicePath(), mountPoint).size() == 0;
}
void CoreUnix::MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const
{
if (GetMountedFilesystems (DevicePath(), mountPoint).size() > 0)
throw MountPointUnavailable (SRC_POS);
list <string> args;
string options;
if (!filesystemType.empty())
{
#ifdef TC_SOLARIS
args.push_back ("-F");
#else
args.push_back ("-t");
#endif
args.push_back (filesystemType);
}
if (readOnly)
options = "-oro";
if (!systemMountOptions.empty())
{
if (options.empty())
options = "-o";
else
options += ",";
options += systemMountOptions;
}
if (!options.empty())
args.push_back (options);
args.push_back ("--");
args.push_back (devicePath);
args.push_back (mountPoint);
Process::Execute ("mount", args);
}
VolumeSlotNumber CoreUnix::MountPointToSlotNumber (const DirectoryPath &mountPoint) const
{
string mountPointStr (mountPoint);
if (mountPointStr.find (GetDefaultMountPointPrefix()) == 0)
{
try
{
return StringConverter::ToUInt32 (StringConverter::GetTrailingNumber (mountPointStr));
}
catch (...) { }
}
return GetFirstFreeSlotNumber();
}
shared_ptr <VolumeInfo> CoreUnix::MountVolume (MountOptions &options)
{
CoalesceSlotNumberAndMountPoint (options);
if (IsVolumeMounted (*options.Path))
throw VolumeAlreadyMounted (SRC_POS);
Cipher::EnableHwSupport (!options.NoHardwareCrypto);
shared_ptr <Volume> volume;
while (true)
{
try
{
volume = OpenVolume (
options.Path,
options.PreserveTimestamps,
options.Password,
options.Keyfiles,
options.Protection,
options.ProtectionPassword,
options.ProtectionKeyfiles,
options.SharedAccessAllowed,
VolumeType::Unknown,
options.UseBackupHeaders,
options.PartitionInSystemEncryptionScope
);
options.Password.reset();
}
catch (SystemException &e)
{
if (options.Protection != VolumeProtection::ReadOnly
&& (e.GetErrorCode() == EROFS || e.GetErrorCode() == EACCES || e.GetErrorCode() == EPERM))
{
// Read-only filesystem
options.Protection = VolumeProtection::ReadOnly;
continue;
}
throw;
}
break;
}
if (options.Path->IsDevice())
{
if (volume->GetFile()->GetDeviceSectorSize() != volume->GetSectorSize())
throw ParameterIncorrect (SRC_POS);
#if defined (TC_LINUX)
if (volume->GetSectorSize() != TC_SECTOR_SIZE_LEGACY)
{
if (options.Protection == VolumeProtection::HiddenVolumeReadOnly)
throw UnsupportedSectorSizeHiddenVolumeProtection();
if (options.NoKernelCrypto)
throw UnsupportedSectorSizeNoKernelCrypto();
}
#endif
}
// Find a free mount point for FUSE service
MountedFilesystemList mountedFilesystems = GetMountedFilesystems ();
string fuseMountPoint;
for (int i = 1; true; i++)
{
stringstream path;
path << GetTempDirectory() << "/" << GetFuseMountDirPrefix() << i;
FilesystemPath fsPath (path.str());
bool inUse = false;
foreach_ref (const MountedFilesystem &mf, mountedFilesystems)
{
if (mf.MountPoint == path.str())
{
inUse = true;
break;
}
}
if (!inUse)
{
try
{
if (fsPath.IsDirectory())
fsPath.Delete();
throw_sys_sub_if (mkdir (path.str().c_str(), S_IRUSR | S_IXUSR) == -1, path.str());
fuseMountPoint = fsPath;
break;
}
catch (...)
{
if (i > 255)
throw TemporaryDirectoryFailure (SRC_POS, StringConverter::ToWide (path.str()));
}
}
}
try
{
FuseService::Mount (volume, options.SlotNumber, fuseMountPoint);
}
catch (...)
{
try
{
DirectoryPath (fuseMountPoint).Delete();
}
catch (...) { }
throw;
}
try
{
// Create a mount directory if a default path has been specified
bool mountDirCreated = false;
string mountPoint;
if (!options.NoFilesystem && options.MountPoint)
{
mountPoint = *options.MountPoint;
#ifndef TC_MACOSX
if (mountPoint.find (GetDefaultMountPointPrefix()) == 0 && !options.MountPoint->IsDirectory())
{
Directory::Create (*options.MountPoint);
try
{
throw_sys_sub_if (chown (mountPoint.c_str(), GetRealUserId(), GetRealGroupId()) == -1, mountPoint);
} catch (ParameterIncorrect&) { }
mountDirCreated = true;
}
#endif
}
try
{
try
{
MountVolumeNative (volume, options, fuseMountPoint);
}
catch (NotApplicable&)
{
MountAuxVolumeImage (fuseMountPoint, options);
}
}
catch (...)
{
if (mountDirCreated)
remove (mountPoint.c_str());
throw;
}
}
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();
}
void CoreUnix::MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const
{
DevicePath loopDev = AttachFileToLoopDevice (string (auxMountPoint) + FuseService::GetVolumeImagePath(), options.Protection == VolumeProtection::ReadOnly);
try
{
FuseService::SendAuxDeviceInfo (auxMountPoint, loopDev, loopDev);
}
catch (...)
{
try
{
DetachLoopDevice (loopDev);
}
catch (...) { }
throw;
}
if (!options.NoFilesystem && options.MountPoint && !options.MountPoint->IsEmpty())
{
MountFilesystem (loopDev, *options.MountPoint,
StringConverter::ToSingle (options.FilesystemType),
options.Protection == VolumeProtection::ReadOnly,
StringConverter::ToSingle (options.FilesystemOptions));
}
}
void CoreUnix::SetFileOwner (const FilesystemPath &path, const UserId &owner) const
{
throw_sys_if (chown (string (path).c_str(), owner.SystemId, (gid_t) -1) == -1);
}
DirectoryPath CoreUnix::SlotNumberToMountPoint (VolumeSlotNumber slotNumber) const
{
if (slotNumber < GetFirstSlotNumber() || slotNumber > GetLastSlotNumber())
throw ParameterIncorrect (SRC_POS);
stringstream s;
s << GetDefaultMountPointPrefix() << slotNumber;
return s.str();
}
}

69
src/Core/Unix/CoreUnix.h Normal file
View File

@@ -0,0 +1,69 @@
/*
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Core_CoreUnix
#define TC_HEADER_Core_CoreUnix
#include "System.h"
#include "Platform/Unix/Process.h"
#include "Core/CoreBase.h"
#include "Core/Unix/MountedFilesystem.h"
namespace TrueCrypt
{
class CoreUnix : public CoreBase
{
public:
CoreUnix ();
virtual ~CoreUnix ();
virtual void CheckFilesystem (shared_ptr <VolumeInfo> mountedVolume, bool repair = false) const;
virtual void DismountFilesystem (const DirectoryPath &mountPoint, bool force) const;
virtual shared_ptr <VolumeInfo> DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles = false, bool syncVolumeInfo = false);
virtual bool FilesystemSupportsLargeFiles (const FilePath &filePath) const;
virtual DirectoryPath GetDeviceMountPoint (const DevicePath &devicePath) const;
virtual uint32 GetDeviceSectorSize (const DevicePath &devicePath) const;
virtual uint64 GetDeviceSize (const DevicePath &devicePath) const;
virtual int GetOSMajorVersion () const { throw NotApplicable (SRC_POS); }
virtual int GetOSMinorVersion () const { throw NotApplicable (SRC_POS); }
virtual VolumeInfoList GetMountedVolumes (const VolumePath &volumePath = VolumePath()) const;
virtual bool IsDevicePresent (const DevicePath &device) const { throw NotApplicable (SRC_POS); }
virtual bool IsInPortableMode () const { return false; }
virtual bool IsMountPointAvailable (const DirectoryPath &mountPoint) const;
virtual bool IsOSVersion (int major, int minor) const { throw NotApplicable (SRC_POS); }
virtual bool IsOSVersionLower (int major, int minor) const { throw NotApplicable (SRC_POS); }
virtual bool IsPasswordCacheEmpty () const { throw NotApplicable (SRC_POS); }
virtual bool HasAdminPrivileges () const { return getuid() == 0 || geteuid() == 0; }
virtual VolumeSlotNumber MountPointToSlotNumber (const DirectoryPath &mountPoint) const;
virtual shared_ptr <VolumeInfo> MountVolume (MountOptions &options);
virtual void SetFileOwner (const FilesystemPath &path, const UserId &owner) const;
virtual DirectoryPath SlotNumberToMountPoint (VolumeSlotNumber slotNumber) const;
virtual void WipePasswordCache () const { throw NotApplicable (SRC_POS); }
protected:
virtual DevicePath AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const { throw NotApplicable (SRC_POS); }
virtual void DetachLoopDevice (const DevicePath &devicePath) const { throw NotApplicable (SRC_POS); }
virtual void DismountNativeVolume (shared_ptr <VolumeInfo> mountedVolume) const { throw NotApplicable (SRC_POS); }
virtual bool FilesystemSupportsUnixPermissions (const DevicePath &devicePath) const;
virtual string GetDefaultMountPointPrefix () const;
virtual string GetFuseMountDirPrefix () const { return ".truecrypt_aux_mnt"; }
virtual MountedFilesystemList GetMountedFilesystems (const DevicePath &devicePath = DevicePath(), const DirectoryPath &mountPoint = DirectoryPath()) const = 0;
virtual uid_t GetRealUserId () const;
virtual gid_t GetRealGroupId () const;
virtual string GetTempDirectory () const;
virtual void MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const;
virtual void 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); }
private:
CoreUnix (const CoreUnix &);
CoreUnix &operator= (const CoreUnix &);
};
}
#endif // TC_HEADER_Core_CoreUnix

View File

@@ -0,0 +1,202 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <fstream>
#include <stdio.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include "CoreFreeBSD.h"
#include "Core/Unix/CoreServiceProxy.h"
namespace TrueCrypt
{
CoreFreeBSD::CoreFreeBSD ()
{
}
CoreFreeBSD::~CoreFreeBSD ()
{
}
DevicePath CoreFreeBSD::AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const
{
list <string> args;
args.push_back ("-a");
args.push_back ("-t");
args.push_back ("vnode");
if (readOnly)
{
args.push_back ("-o");
args.push_back ("readonly");
}
args.push_back ("-f");
args.push_back (filePath);
string dev = StringConverter::Trim (Process::Execute ("mdconfig", args));
if (dev.find ("/") == string::npos)
dev = string ("/dev/") + dev;
return dev;
}
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"))
#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 = "";
#else
foreach (const string &partLetter, StringConverter::Split (",a,b,c,d,e,f,g,h", ",", true))
#endif
{
stringstream partPath;
partPath << devPath.str() << "s" << partNumber << partLetter;
if (FilesystemPath (partPath.str()).IsBlockDevice() || FilesystemPath (partPath.str()).IsCharacterDevice())
{
make_shared_auto (HostDevice, partition);
partition->Path = partPath.str();
if (!pathListOnly)
{
try
{
partition->Size = GetDeviceSize (partition->Path);
}
catch (...)
{
partition->Size = 0;
}
partition->MountPoint = GetDeviceMountPoint (partition->Path);
partition->SystemNumber = 0;
}
device->Partitions.push_back (partition);
}
}
}
}
}
}
return devices;
}
MountedFilesystemList CoreFreeBSD::GetMountedFilesystems (const DevicePath &devicePath, const DirectoryPath &mountPoint) const
{
static Mutex mutex;
ScopeLock sl (mutex);
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
{
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);
}
catch (ExecutedProcessFailed&)
{
if (!filesystemType.empty())
throw;
CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType, readOnly, systemMountOptions);
}
}
#ifdef TC_FREEBSD
auto_ptr <CoreBase> Core (new CoreServiceProxy <CoreFreeBSD>);
auto_ptr <CoreBase> CoreDirect (new CoreFreeBSD);
#endif
}

View File

@@ -0,0 +1,37 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Core_CoreFreeBSD
#define TC_HEADER_Core_CoreFreeBSD
#include "System.h"
#include "Core/Unix/CoreUnix.h"
namespace TrueCrypt
{
class CoreFreeBSD : public CoreUnix
{
public:
CoreFreeBSD ();
virtual ~CoreFreeBSD ();
virtual HostDeviceList GetHostDevices (bool pathListOnly = false) const;
protected:
virtual DevicePath AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const;
virtual void DetachLoopDevice (const DevicePath &devicePath) const;
virtual MountedFilesystemList GetMountedFilesystems (const DevicePath &devicePath = DevicePath(), const DirectoryPath &mountPoint = DirectoryPath()) const;
virtual void MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const;
private:
CoreFreeBSD (const CoreFreeBSD &);
CoreFreeBSD &operator= (const CoreFreeBSD &);
};
}
#endif // TC_HEADER_Core_CoreFreeBSD

View File

@@ -0,0 +1,12 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Platform_FreeBSD_System
#define TC_HEADER_Platform_FreeBSD_System
#endif // TC_HEADER_Platform_FreeBSD_System

View File

@@ -0,0 +1,477 @@
/*
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt 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/EncryptionModeLRW.h"
#include "Volume/EncryptionModeXTS.h"
#include "Driver/Fuse/FuseService.h"
#include "Core/Unix/CoreServiceProxy.h"
namespace TrueCrypt
{
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");
for (int devIndex = 0; devIndex < 256; devIndex++)
{
string loopDev;
foreach (const string &loopPath, loopPaths)
{
loopDev = loopPath + StringConverter::ToSingle (devIndex);
if (FilesystemPath (loopDev).IsBlockDevice())
break;
}
if (loopDev.empty())
continue;
list <string> args;
list <string>::iterator readOnlyArg;
if (readOnly)
{
args.push_back ("-r");
readOnlyArg = --args.end();
}
args.push_back ("--");
args.push_back (loopDev);
args.push_back (filePath);
try
{
Process::Execute ("losetup", args);
return loopDev;
}
catch (ExecutedProcessFailed&)
{
if (readOnly)
{
try
{
args.erase (readOnlyArg);
Process::Execute ("losetup", args);
return loopDev;
}
catch (ExecutedProcessFailed&) { }
}
}
}
throw LoopDeviceSetupFailed (SRC_POS, wstring (filePath));
}
void CoreLinux::DetachLoopDevice (const DevicePath &devicePath) const
{
list <string> args;
args.push_back ("-d");
args.push_back (devicePath);
for (int t = 0; true; t++)
{
try
{
Process::Execute ("losetup", args);
break;
}
catch (ExecutedProcessFailed&)
{
if (t > 5)
throw;
Thread::Sleep (200);
}
}
}
void CoreLinux::DismountNativeVolume (shared_ptr <VolumeInfo> mountedVolume) const
{
string devPath = mountedVolume->VirtualDevice;
if (devPath.find ("/dev/mapper/truecrypt") != 0)
throw NotApplicable (SRC_POS);
size_t devCount = 0;
while (FilesystemPath (devPath).IsBlockDevice())
{
list <string> dmsetupArgs;
dmsetupArgs.push_back ("remove");
dmsetupArgs.push_back (StringConverter::Split (devPath, "/").back());
for (int t = 0; true; t++)
{
try
{
Process::Execute ("dmsetup", dmsetupArgs);
break;
}
catch (...)
{
if (t > 20)
throw;
Thread::Sleep (100);
}
}
for (int t = 0; FilesystemPath (devPath).IsBlockDevice() && t < 20; t++)
{
Thread::Sleep (100);
}
devPath = string (mountedVolume->VirtualDevice) + "_" + StringConverter::ToSingle (devCount++);
}
}
HostDeviceList CoreLinux::GetHostDevices (bool pathListOnly) const
{
HostDeviceList devices;
TextReader tr ("/proc/partitions");
string line;
while (tr.ReadLine (line))
{
vector <string> fields = StringConverter::Split (line);
if (fields.size() != 4
|| fields[3].find ("loop") == 0 // skip loop devices
|| fields[3].find ("cloop") == 0
|| fields[3].find ("ram") == 0 // skip RAM devices
|| fields[3].find ("dm-") == 0 // skip device mapper devices
|| fields[2] == "1" // skip extended partitions
)
continue;
try
{
StringConverter::ToUInt32 (fields[0]);
}
catch (...)
{
continue;
}
try
{
make_shared_auto (HostDevice, hostDevice);
hostDevice->Path = string (fields[3].find ("/dev/") == string::npos ? "/dev/" : "") + fields[3];
if (!pathListOnly)
{
hostDevice->Size = StringConverter::ToUInt64 (fields[2]) * 1024;
hostDevice->MountPoint = GetDeviceMountPoint (hostDevice->Path);
hostDevice->SystemNumber = 0;
}
try
{
StringConverter::GetTrailingNumber (fields[3]);
if (devices.size() > 0)
{
HostDevice &prevDev = **--devices.end();
if (string (hostDevice->Path).find (prevDev.Path) == 0)
{
prevDev.Partitions.push_back (hostDevice);
continue;
}
}
}
catch (...) { }
devices.push_back (hostDevice);
continue;
}
catch (...)
{
continue;
}
}
return devices;
}
MountedFilesystemList CoreLinux::GetMountedFilesystems (const DevicePath &devicePath, const DirectoryPath &mountPoint) const
{
MountedFilesystemList mountedFilesystems;
DevicePath realDevicePath = devicePath;
if (!devicePath.IsEmpty())
{
char *resolvedPath = realpath (string (devicePath).c_str(), NULL);
if (resolvedPath)
{
realDevicePath = resolvedPath;
free (resolvedPath);
}
}
FILE *mtab = fopen ("/etc/mtab", "r");
if (!mtab)
mtab = fopen ("/proc/mounts", "r");
throw_sys_sub_if (!mtab, "/proc/mounts");
finally_do_arg (FILE *, mtab, { fclose (finally_arg); });
static Mutex mutex;
ScopeLock sl (mutex);
struct mntent *entry;
while ((entry = getmntent (mtab)) != nullptr)
{
make_shared_auto (MountedFilesystem, mf);
if (entry->mnt_fsname)
mf->Device = DevicePath (entry->mnt_fsname);
else
continue;
if (entry->mnt_dir)
mf->MountPoint = DirectoryPath (entry->mnt_dir);
if (entry->mnt_type)
mf->Type = entry->mnt_type;
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 lrw = (typeid (*volume->GetEncryptionMode()) == typeid (EncryptionModeLRW));
if (options.NoKernelCrypto
|| (!xts && (!lrw || volume->GetEncryptionAlgorithm()->GetCiphers().size() > 1 || volume->GetEncryptionAlgorithm()->GetMinBlockSize() != 16))
|| 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 (...) { }
}
bool loopDevAttached = false;
bool nativeDevCreated = false;
bool filesystemMounted = false;
// Attach volume to loopback device if required
VolumePath volumePath = volume->GetPath();
if (!volumePath.IsDevice())
{
volumePath = AttachFileToLoopDevice (volumePath, options.Protection == VolumeProtection::ReadOnly);
loopDevAttached = true;
}
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()));
// 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));
if (lrw && i >= 16)
continue;
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 << "truecrypt" << 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);
// Wait for the device to be created
for (int t = 0; true; t++)
{
try
{
FilesystemPath (nativeDevPath).GetType();
break;
}
catch (...)
{
if (t > 20)
throw;
Thread::Sleep (100);
}
}
nativeDevCreated = true;
++nativeDevCount;
}
// Test whether the device mapper is able to read and decrypt the last sector
SecureBuffer lastSectorBuf (volume->GetSectorSize());
uint64 lastSectorOffset = volume->GetSize() - volume->GetSectorSize();
File nativeDev;
nativeDev.Open (nativeDevPath);
nativeDev.ReadAt (lastSectorBuf, lastSectorOffset);
SecureBuffer lastSectorBuf2 (volume->GetSectorSize());
volume->ReadSectors (lastSectorBuf2, lastSectorOffset);
if (memcmp (lastSectorBuf.Ptr(), lastSectorBuf2.Ptr(), volume->GetSectorSize()) != 0)
throw KernelCryptoServiceTestFailed (SRC_POS);
// Mount filesystem
if (!options.NoFilesystem && options.MountPoint && !options.MountPoint->IsEmpty())
{
MountFilesystem (nativeDevPath, *options.MountPoint,
StringConverter::ToSingle (options.FilesystemType),
options.Protection == VolumeProtection::ReadOnly,
StringConverter::ToSingle (options.FilesystemOptions));
filesystemMounted = true;
}
FuseService::SendAuxDeviceInfo (auxMountPoint, nativeDevPath, volumePath);
}
catch (...)
{
try
{
if (filesystemMounted)
DismountFilesystem (*options.MountPoint, true);
}
catch (...) { }
try
{
if (nativeDevCreated)
{
make_shared_auto (VolumeInfo, vol);
vol->VirtualDevice = nativeDevPath;
DismountNativeVolume (vol);
}
}
catch (...) { }
try
{
if (loopDevAttached)
DetachLoopDevice (volumePath);
}
catch (...) { }
throw;
}
}
auto_ptr <CoreBase> Core (new CoreServiceProxy <CoreLinux>);
auto_ptr <CoreBase> CoreDirect (new CoreLinux);
}

View File

@@ -0,0 +1,39 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Core_CoreLinux
#define TC_HEADER_Core_CoreLinux
#include "System.h"
#include "Core/Unix/CoreUnix.h"
namespace TrueCrypt
{
class CoreLinux : public CoreUnix
{
public:
CoreLinux ();
virtual ~CoreLinux ();
virtual HostDeviceList GetHostDevices (bool pathListOnly = false) const;
protected:
virtual DevicePath AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const;
virtual void DetachLoopDevice (const DevicePath &devicePath) const;
virtual void DismountNativeVolume (shared_ptr <VolumeInfo> mountedVolume) const;
virtual MountedFilesystemList GetMountedFilesystems (const DevicePath &devicePath = DevicePath(), const DirectoryPath &mountPoint = DirectoryPath()) const;
virtual void MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const;
virtual void MountVolumeNative (shared_ptr <Volume> volume, MountOptions &options, const DirectoryPath &auxMountPoint) const;
private:
CoreLinux (const CoreLinux &);
CoreLinux &operator= (const CoreLinux &);
};
}
#endif // TC_HEADER_Core_CoreLinux

View File

@@ -0,0 +1,12 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Platform_Linux_System
#define TC_HEADER_Platform_Linux_System
#endif // TC_HEADER_Platform_Linux_System

View File

@@ -0,0 +1,215 @@
/*
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <fstream>
#include <stdio.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "CoreMacOSX.h"
#include "Driver/Fuse/FuseService.h"
#include "Core/Unix/CoreServiceProxy.h"
namespace TrueCrypt
{
CoreMacOSX::CoreMacOSX ()
{
}
CoreMacOSX::~CoreMacOSX ()
{
}
shared_ptr <VolumeInfo> CoreMacOSX::DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo)
{
if (!mountedVolume->VirtualDevice.IsEmpty() && mountedVolume->VirtualDevice.IsBlockDevice())
{
list <string> args;
args.push_back ("detach");
args.push_back (mountedVolume->VirtualDevice);
if (ignoreOpenFiles)
args.push_back ("-force");
try
{
Process::Execute ("hdiutil", args);
}
catch (ExecutedProcessFailed &e)
{
if (!ignoreOpenFiles)
{
string err = e.GetErrorOutput();
if (err.find ("couldn't unmount") != string::npos
|| err.find ("busy") != string::npos
|| err.find ("49153") != string::npos)
{
throw MountedVolumeInUse (SRC_POS);
}
}
throw;
}
}
if (syncVolumeInfo || mountedVolume->Protection == VolumeProtection::HiddenVolumeReadOnly)
{
sync();
VolumeInfoList ml = GetMountedVolumes (mountedVolume->Path);
if (ml.size() > 0)
mountedVolume = ml.front();
}
list <string> args;
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");
Process::Execute ("open", args);
}
void CoreMacOSX::MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const
{
// Check FUSE version
char fuseVersionString[MAXHOSTNAMELEN + 1] = { 0 };
size_t fuseVersionStringLength = MAXHOSTNAMELEN;
if (sysctlbyname ("macfuse.version.number", fuseVersionString, &fuseVersionStringLength, NULL, 0) != 0)
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 < 1 || (fuseVersionMajor == 1 && fuseVersionMinor < 3))
throw HigherFuseVersionRequired (SRC_POS);
// 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;
while (true)
{
try
{
xml = Process::Execute ("hdiutil", args);
break;
}
catch (ExecutedProcessFailed &e)
{
if (e.GetErrorOutput().find ("noautofsck") != string::npos)
{
args.remove ("-noautofsck");
continue;
}
throw;
}
}
size_t p = xml.find ("<key>dev-entry</key>");
if (p == string::npos)
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));
try
{
FuseService::SendAuxDeviceInfo (auxMountPoint, virtualDev);
}
catch (...)
{
try
{
list <string> args;
args.push_back ("detach");
args.push_back (volImage);
args.push_back ("-force");
Process::Execute ("hdiutil", args);
}
catch (ExecutedProcessFailed&) { }
throw;
}
}
auto_ptr <CoreBase> Core (new CoreServiceProxy <CoreMacOSX>);
auto_ptr <CoreBase> CoreDirect (new CoreMacOSX);
}

View File

@@ -0,0 +1,36 @@
/*
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Core_CoreMacOSX
#define TC_HEADER_Core_CoreMacOSX
#include "System.h"
#include "Core/Unix/FreeBSD/CoreFreeBSD.h"
namespace TrueCrypt
{
class CoreMacOSX : public CoreFreeBSD
{
public:
CoreMacOSX ();
virtual ~CoreMacOSX ();
virtual void CheckFilesystem (shared_ptr <VolumeInfo> mountedVolume, bool repair = false) const;
virtual shared_ptr <VolumeInfo> DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles = false, bool syncVolumeInfo = false);
virtual string GetDefaultMountPointPrefix () const { return "/Volumes/truecrypt"; }
protected:
virtual void MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const;
private:
CoreMacOSX (const CoreMacOSX &);
CoreMacOSX &operator= (const CoreMacOSX &);
};
}
#endif // TC_HEADER_Core_CoreMacOSX

View File

@@ -0,0 +1,12 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Platform_MacOSX_System
#define TC_HEADER_Platform_MacOSX_System
#endif // TC_HEADER_Platform_MacOSX_System

View File

@@ -0,0 +1,27 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Core_Unix_MountedFilesystem
#define TC_HEADER_Core_Unix_MountedFilesystem
#include "Platform/Platform.h"
namespace TrueCrypt
{
struct MountedFilesystem
{
public:
DevicePath Device;
DirectoryPath MountPoint;
string Type;
};
typedef list < shared_ptr <MountedFilesystem> > MountedFilesystemList;
}
#endif // TC_HEADER_Core_Unix_MountedFilesystem

View File

@@ -0,0 +1,174 @@
/*
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/mntent.h>
#include <sys/mnttab.h>
#include "CoreSolaris.h"
#include "Core/Unix/CoreServiceProxy.h"
namespace TrueCrypt
{
CoreSolaris::CoreSolaris ()
{
}
CoreSolaris::~CoreSolaris ()
{
}
DevicePath CoreSolaris::AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const
{
list <string> args;
args.push_back ("-a");
args.push_back (filePath);
return StringConverter::Trim (Process::Execute ("lofiadm", args));
}
void CoreSolaris::DetachLoopDevice (const DevicePath &devicePath) const
{
list <string> args;
args.push_back ("-d");
args.push_back (devicePath);
for (int t = 0; true; t++)
{
try
{
Process::Execute ("lofiadm", args);
break;
}
catch (ExecutedProcessFailed&)
{
if (t > 5)
throw;
Thread::Sleep (200);
}
}
}
HostDeviceList CoreSolaris::GetHostDevices (bool pathListOnly) const
{
HostDeviceList devices;
foreach_ref (const FilePath &devPath, Directory::GetFilePaths ("/dev/rdsk", false))
{
string drivePath = devPath;
if (drivePath.rfind ("p0") == drivePath.size() - 2)
{
make_shared_auto (HostDevice, device);
device->Path = drivePath;
try
{
device->Size = GetDeviceSize (device->Path);
}
catch (...)
{
device->Size = 0;
}
if (device->Size == 0)
continue;
device->MountPoint = GetDeviceMountPoint (device->Path);
device->SystemNumber = 0;
devices.push_back (device);
for (int partNumber = 1; partNumber <= 32; partNumber++)
{
stringstream partPath;
partPath << drivePath.substr (0, drivePath.size() - 1) << partNumber;
if (FilesystemPath (partPath.str()).IsBlockDevice() || FilesystemPath (partPath.str()).IsCharacterDevice())
{
make_shared_auto (HostDevice, partition);
partition->Path = partPath.str();
try
{
partition->Size = GetDeviceSize (partition->Path);
}
catch (...)
{
partition->Size = 0;
}
if (partition->Size == 0)
continue;
partition->MountPoint = GetDeviceMountPoint (partition->Path);
partition->SystemNumber = 0;
device->Partitions.push_back (partition);
}
}
}
}
return devices;
}
MountedFilesystemList CoreSolaris::GetMountedFilesystems (const DevicePath &devicePath, const DirectoryPath &mountPoint) const
{
MountedFilesystemList mountedFilesystems;
FILE *mtab = fopen ("/etc/mnttab", "r");
throw_sys_sub_if (!mtab, "/etc/mnttab");
finally_do_arg (FILE *, mtab, { fclose (finally_arg); });
int getmntentResult;
struct mnttab entry;
while ((getmntentResult = getmntent (mtab, &entry)) == 0)
{
make_shared_auto (MountedFilesystem, mf);
if (entry.mnt_special)
mf->Device = DevicePath (entry.mnt_special);
else
continue;
if (entry.mnt_mountp)
mf->MountPoint = DirectoryPath (entry.mnt_mountp);
if (entry.mnt_fstype)
mf->Type = entry.mnt_fstype;
if ((devicePath.IsEmpty() || devicePath == mf->Device) && (mountPoint.IsEmpty() || mountPoint == mf->MountPoint))
mountedFilesystems.push_back (mf);
}
throw_sys_if (getmntentResult > 0);
return mountedFilesystems;
}
void CoreSolaris::MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const
{
try
{
// Try to mount FAT by default as mount is unable to probe filesystem type on Solaris
CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType.empty() ? "pcfs" : filesystemType, readOnly, systemMountOptions);
}
catch (ExecutedProcessFailed&)
{
if (!filesystemType.empty())
throw;
CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType, readOnly, systemMountOptions);
}
}
auto_ptr <CoreBase> Core (new CoreServiceProxy <CoreSolaris>);
auto_ptr <CoreBase> CoreDirect (new CoreSolaris);
}

View File

@@ -0,0 +1,37 @@
/*
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Core_CoreSolaris
#define TC_HEADER_Core_CoreSolaris
#include "System.h"
#include "Core/Unix/CoreUnix.h"
namespace TrueCrypt
{
class CoreSolaris : public CoreUnix
{
public:
CoreSolaris ();
virtual ~CoreSolaris ();
virtual HostDeviceList GetHostDevices (bool pathListOnly = false) const;
protected:
virtual DevicePath AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const;
virtual void DetachLoopDevice (const DevicePath &devicePath) const;
virtual MountedFilesystemList GetMountedFilesystems (const DevicePath &devicePath = DevicePath(), const DirectoryPath &mountPoint = DirectoryPath()) const;
virtual void MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const;
private:
CoreSolaris (const CoreSolaris &);
CoreSolaris &operator= (const CoreSolaris &);
};
}
#endif // TC_HEADER_Core_CoreSolaris

View File

@@ -0,0 +1,12 @@
/*
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Platform_Solaris_System
#define TC_HEADER_Platform_Solaris_System
#endif // TC_HEADER_Platform_Solaris_System

12
src/Core/Unix/System.h Normal file
View File

@@ -0,0 +1,12 @@
/*
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
Governed by the TrueCrypt License 3.0 the full text of which is contained in
the file License.txt included in TrueCrypt binary and source code distribution
packages.
*/
#ifndef TC_HEADER_Platform_Unix_System
#define TC_HEADER_Platform_Unix_System
#endif // TC_HEADER_Platform_Unix_System