Пример #1
0
FileBase* FileTable::create_as(const id_type& id, int type)
{
    if (is_readonly())
        throw OSException(EROFS);
    if (m_opened.find(id) != m_opened.end() || m_closed.find(id) != m_closed.end())
        throw OSException(EEXIST);

    std::shared_ptr<FileStream> data_fd, meta_fd;
    std::tie(data_fd, meta_fd) = m_fio->create(id);
    auto fb = btree_make_file_from_type(
        type, data_fd, meta_fd, m_master_key, id, is_auth_enabled(), m_block_size, m_iv_size);
    m_opened.emplace(id, fb);
    fb->setref(1);
    return fb.get();
}
Пример #2
0
QC_BASE_NAMESPACE_BEGIN

//==============================================================================
// ThreadLocal::ThreadLocal
//
/**
   Default constructor.  Uses the operating-system's threading library to 
   allocate a new thread-local variable.

   The value of the variable is automatically initialized to zero for every
   thread.
*/
//==============================================================================
ThreadLocal::ThreadLocal()
{
#if defined(QC_WIN32_THREADS)

	m_key = ::TlsAlloc();
	if(m_key == (DWORD)-1)
	{
		throw Win32Exception(::GetLastError());
	}

#elif defined(QC_POSIX_THREADS)

	int status = ::pthread_key_create(&m_key, 0);
	if(status != 0)
	{
		throw OSException(status, QC_T("pthread_key_create"));
	}

#endif
}
Пример #3
0
bool SimpleDirectory::add_entry(const std::string& name, const id_type& id, int type)
{
    if (name.size() > MAX_FILENAME_LENGTH)
        throw OSException(ENAMETOOLONG);
    auto rv = m_table.emplace(name, std::make_pair(id, type));
    if (rv.second)
        m_dirty = true;
    return rv.second;
}
Пример #4
0
ssize_t FileBase::getxattr(const char* name, char* value, size_t size)
{
    if (!name)
        throw OSException(EFAULT);

    auto true_size = fgetxattr_wrapper(file_descriptor(), name, value, size);
    if (true_size < 0)
        throw OSException(errno);
    if (!value)
        return true_size;

    byte meta[XATTR_IV_LENGTH + XATTR_MAC_LENGTH];
    auto true_meta_size = fgetxattr_wrapper(m_meta_fd, name, meta, sizeof(meta));
    if (true_meta_size < 0)
    {
        if (errno == ERANGE)
            errno = EIO;
        throw OSException(errno);
    }

    auto name_len = strlen(name);
    std::unique_ptr<byte[]> header(new byte[name_len + ID_LENGTH]);
    memcpy(header.get(), get_id().data(), ID_LENGTH);
    memcpy(header.get() + ID_LENGTH, name, name_len);

    byte* iv = meta;
    byte* mac = meta + XATTR_IV_LENGTH;
    byte* ciphertext = reinterpret_cast<byte*>(value);

    bool success = aes_gcm_decrypt(ciphertext,
                                   true_size,
                                   header.get(),
                                   name_len + ID_LENGTH,
                                   get_key().data(),
                                   get_key().size(),
                                   iv,
                                   XATTR_IV_LENGTH,
                                   mac,
                                   XATTR_MAC_LENGTH,
                                   value);
    if (m_check && !success)
        throw XattrVerificationException(get_id(), name);
    return true_size;
}
Пример #5
0
void FileBase::removexattr(const char* name)
{
#ifdef __APPLE__
    auto rc = ::fremovexattr(file_descriptor(), name, 0);
#else
    auto rc = ::fremovexattr(file_descriptor(), name);
#endif
    if (rc < 0)
        throw OSException(errno);
}
Пример #6
0
ssize_t FileBase::listxattr(char* buffer, size_t size)
{
#ifdef __APPLE__
    auto rc = ::flistxattr(file_descriptor(), buffer, size, 0);
#else
    auto rc = ::flistxattr(file_descriptor(), buffer, size);
#endif
    if (rc < 0)
        throw OSException(errno);
    return rc;
}
Пример #7
0
void FileBase::setxattr(const char* name, const char* value, size_t size, int flags)
{
    if (!name || !value)
        throw OSException(EFAULT);

    std::unique_ptr<byte[]> buffer(new byte[size]);
    byte* ciphertext = buffer.get();

    byte meta[XATTR_MAC_LENGTH + XATTR_IV_LENGTH];
    byte* iv = meta;
    byte* mac = iv + XATTR_IV_LENGTH;
    generate_random(iv, XATTR_IV_LENGTH);

    auto name_len = strlen(name);
    std::unique_ptr<byte[]> header(new byte[name_len + ID_LENGTH]);
    memcpy(header.get(), get_id().data(), ID_LENGTH);
    memcpy(header.get() + ID_LENGTH, name, name_len);

    aes_gcm_encrypt(value,
                    size,
                    header.get(),
                    name_len + ID_LENGTH,
                    get_key().data(),
                    get_key().size(),
                    iv,
                    XATTR_IV_LENGTH,
                    mac,
                    XATTR_MAC_LENGTH,
                    ciphertext);

    auto rc = fsetxattr_wrapper(file_descriptor(), name, ciphertext, size, flags);
    if (rc < 0)
        throw OSException(errno);
    rc = fsetxattr_wrapper(m_meta_fd, name, meta, sizeof(meta), flags);
    if (rc < 0)
        throw OSException(errno);
}
Пример #8
0
	bool BinaryFile::Save(const string& filename, const Buffer& buffer)
	{
		DWORD error = GetLastError();

		HANDLE hFile = CreateFile(filename.Data(), GENERIC_WRITE, 0, 0,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
		CHECK_SYS_ERROR(L"Error in binary file, open file for saving " + filename);

		DWORD read;
		WriteFile(hFile, (LPCVOID)buffer.StartPointer(), (DWORD)buffer.GetPosition(), &read, 0);
		CHECK_SYS_ERROR(L"Error in binary file, can't write data to file " + filename);

		if (read != buffer.GetPosition())
			throw OSException(L"Error in binary file, written data is less than should be " + filename);

		CloseHandle(hFile);
		CHECK_SYS_ERROR(L"Saving binary file failed " + filename);
		return true;
	}
Пример #9
0
	bool BinaryFile::Load(const string& filename, Buffer& buffer)
	{
		DWORD error = GetLastError();

		HANDLE hFile = CreateFile(filename.Data(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
		CHECK_SYS_ERROR(L"Error in binary file, can't load it " + filename);

		int size = GetFileSize(hFile, 0);
		buffer.SetSize(size);

		DWORD read;
		ReadFile(hFile, buffer.StartPointer(), size, &read, 0);
		CHECK_SYS_ERROR(L"Error in binary file, can't read data " + filename);

		if (read != size)
			throw OSException(L"Error in binary file, read data less than file contains, possible bad staff happenes " + filename);

		CloseHandle(hFile);
		CHECK_SYS_ERROR(L"Binary file load failed " + filename);
		return true;
	}
Пример #10
0
	void CheckOSError(LONG code, const System::string& msg)
	{
		string error;

		if (code != S_OK)
		{
			HLOCAL hLocal = 0;
			if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_IGNORE_INSERTS,
				0, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (PTSTR)&hLocal, 0, 0))
			{
				LPVOID p = LocalLock(hLocal);
			    error = string((wchar_t*)p) + string::Format(L"(Code: 0x%X) (MS Windows)", code);
				LocalFree(hLocal);
			}
			else
			{
				error = L"Unknown error from GetLastError()";
			}
			throw OSException(error);
		}		
	}
Пример #11
0
	bool BinaryFile::Append(const string& filename, const Buffer& buffer)
	{
		DWORD error = GetLastError();

		HANDLE hFile = CreateFile(filename.Data(), GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
		CHECK_SYS_ERROR(L"Error in binary file, can't open file for appending it " + filename);

		DWORD offset = GetFileSize(hFile, 0);
		SetFilePointer(hFile, offset, 0, FILE_BEGIN);

		DWORD read;

		WriteFile(hFile, (LPCVOID)buffer.StartPointer(), (DWORD)buffer.GetPosition(), &read, 0);
		CHECK_SYS_ERROR(L"Error in binary file, can't write data to file " + filename);

		if (read != buffer.GetPosition())
			throw OSException(L"Error in binary file, written data is less than should be in " + filename);

		CloseHandle(hFile);
		CHECK_SYS_ERROR(L"Failed to append a file " + filename);
		return true;
	}
Пример #12
0
FileBase* FileTable::open_as(const id_type& id, int type)
{
    auto it = m_opened.find(id);
    if (it != m_opened.end())
    {
        if (it->second->type() != type)
            throw OSException(FileBase::error_number_for_not(type));
        it->second->incref();
        return it->second.get();
    }

    it = m_closed.find(id);
    if (it != m_closed.end())
    {
        if (it->second->type() != type)
        {
            m_closed.erase(it);
        }
        else
        {
            auto fb = it->second;
            m_opened.emplace(*it);
            m_closed.erase(it);
            fb->setref(1);
            return fb.get();
        }
    }

    std::shared_ptr<FileStream> data_fd, meta_fd;
    std::tie(data_fd, meta_fd) = m_fio->open(id);
    auto fb = btree_make_file_from_type(
        type, data_fd, meta_fd, m_master_key, id, is_auth_enabled(), m_block_size, m_iv_size);
    m_opened.emplace(id, fb);
    fb->setref(1);
    return fb.get();
}