Exemple #1
0
void PwDatabaseFacade::unlock(const QString &dbFilePath, const QString &password, const QString &keyFilePath) {
    // delete any leftovers
    clear();

    // Load DB file to memory
    QFile dbFile (dbFilePath);
    if (!dbFile.open(QIODevice::ReadOnly)) {
        LOG("Cannot open DB file: '%s' Error: %d. Message: %s",
                dbFilePath.toUtf8().constData(), dbFile.error(),
                dbFile.errorString().toUtf8().constData());
        emit fileOpenError(tr("Cannot open database file", "An error message shown when the file is not available or cannot be opened."), dbFile.errorString());
        return;
    }
    LOG("DB file open ok");
    QByteArray dbFileData = dbFile.readAll();
    if (dbFile.error() != QFile::NoError) {
        // There was a problem reading the file
        emit fileOpenError(tr("Error loading database file", "An error message shown when the file cannot be loaded/read."), dbFile.errorString());
        dbFile.close();
        return;
    }
    dbFile.close();

    if (dbFileData.isEmpty()) {
        // The file is ok, but empty
        emit dbUnlockError(tr("Database file is empty", "An error message"), PwDatabase::DB_FILE_EMPTY);
        return;
    }

    // Load key file to memory
    QByteArray keyFileData;
    if (!loadKeyFile(keyFilePath, keyFileData))
        return;

    // Get suitable DB processor (KeePass1 vs KeePass2)
    db = createDatabaseInstance(dbFileData);
    if (!db) {
        emit dbUnlockError(tr("Unknown database format", "An error message for unrecognized/unsupported database file structure."), PwDatabase::UNKNOWN_DB_FORMAT);
        return;
    }

    // let DB instance know the original file path
    db->setDatabaseFilePath(dbFilePath);

    // Setup signal forwarding
    connectDatabaseSignals();

    // Do the actual unlocking/loading
    db->load(dbFileData, password, keyFileData);
    Util::safeClear(dbFileData);
    Util::safeClear(keyFileData);
}
Exemple #2
0
/* Extracts the file named filename with size fileSize from archive. The file
 * pointer in archive must be pointing to the beginning of the body of the file
 * to extract. Prints a message to stderr if the extraction cannot be done.
 * Moves the file pointer to the end of the body of the file extracted.
 * Returns -1 if the archive is corrupted, else returns 0. */
char extractFile(FILE* archive, char* filename, unsigned int fileSize)
{
    int currentLen = 0;
    char* currentStr = NULL;
    
    while(currentLen < strlen(filename))
    {
        // count chars in filename up to the next slash, and include the slash
        currentLen += strcspn(&(filename[currentLen]), "/") + 1;
        
        currentStr = malloc(sizeof(char) * (currentLen + 1));
        
        strncpy(currentStr, filename, currentLen);
        currentStr[currentLen] = '\0';
        
        if(currentStr[currentLen - 1] == '/') // if it's a directory
        {
            ensureDirExists(currentStr);
        }
        else // it's a regular file
        {
            FILE* extractedFile = fopen(filename, "wb+");
            
            if(extractedFile)
            {
                for(unsigned int i = 0; i < fileSize; i++)
                {
                    int c = fgetc(archive);
                    if(c == EOF)
                    {
                        return -1;
                    }
                    else
                    {
                        fputc(c, extractedFile);
                    }
                }
                fclose(extractedFile);
            }
            else
            {
                fileOpenError(filename);
            }
        }
    }
    
    if(currentStr) free(currentStr);
    return 0;
}
Exemple #3
0
/**
 * Loads given key file to the given buffer. No processing, just load or emit error signals.
 * Empty file path is ok.
 * Returns true if successful, otherwise emits fileOpenError signal and returns false.
 */
bool PwDatabaseFacade::loadKeyFile(const QString& keyFilePath, QByteArray& keyFileData) const {
    if (!keyFilePath.isEmpty()) {
        QFile keyFile (keyFilePath);
        if (!keyFile.open(QIODevice::ReadOnly)) {
            LOG("Cannot open key file: '%s' Error: %d. Message: %s",
                    keyFilePath.toUtf8().constData(), keyFile.error(),
                    keyFile.errorString().toUtf8().constData());
            emit fileOpenError(tr("Cannot open key file", "An error message shown when the file is not available or cannot be read. See 'key file' in the supplied thesaurus."), keyFile.errorString());
            return false;
        }
        keyFileData = keyFile.readAll();
        LOG("Key file is: %s", (keyFileData.isEmpty() ? "empty" : "non-empty"));
        keyFile.close();
    } else {
        LOG("Key file not provided");
    }
    return true;
}
Exemple #4
0
FAR_RTRN farAdd(char* archiveName, char** fileArgs, unsigned char numFileArgs)
{
    FILE* oldArchive; // the archive file named archiveName
    FILE* tempArchive; // the temp archive with name TEMP_ARCHIVE_NAME
    FILE* fileToAdd = NULL; // a file with name from fileArgs to add to the
                            // archive
    
    unsigned int newNumFiles = 0; // the total number of files in the NEW
                                  // archive
    unsigned int oldNumFiles; // the total number of files in the OLD archive
    
    charBuffer* filename; // the name of a file being copied from oldArchive
    unsigned int fileSize; // the size of the current file in oldArchive
    
    struct stat fileStat; // holds data from any stat() calls
    DIR* dir; // pointer to a directory-type file with name from fileArgs
    
    // check for no-args
    if(numFileArgs == 0)
    {
        return SUCCESS;
    }
    
    /* eliminates invalid args (and prints errors) and expands directories to
     * include their contents */
    fileList* validArgs = fileListNew(fileArgs, numFileArgs);
    
    oldArchive = fopen(archiveName, "rb+");
    
    // read the number of files in oldArchive
    if(oldArchive)
    {
        if(fread(&oldNumFiles, sizeof(unsigned int), 1, oldArchive) < 1)
        {
            fclose(oldArchive);
            fileListDelete(validArgs);
            return corruptedArchiveError();
        }
    }
    else
    {
        oldNumFiles = 0;
    }
    
    // open the temp archive and check for error
    tempArchive = fopen(TEMP_ARCHIVE_NAME, "wb+");
    if(!tempArchive)
    {
        fclose(oldArchive);
        fileListDelete(validArgs);
        return openTempArchiveError();
    }
    
    // write numFiles simply to reserve the uint space;
    // it will be overwritten at the end
    fwrite(&newNumFiles, sizeof(unsigned int), 1, tempArchive);
    
    filename = charBufferNew();
    
    // copy oldArchive to tempArchive, not copying any entries that appear in
    // validArgs
    for(unsigned int i = 0; i < oldNumFiles; i++)
    {
        // get filename and fileSize
        if(getFileName(oldArchive, filename) ||
           fread(&fileSize, sizeof(unsigned int), 1, oldArchive) < 1)
        {
            fclose(oldArchive);
            fclose(tempArchive);
            unlink(TEMP_ARCHIVE_NAME);
            charBufferDelete(filename);
            fileListDelete(validArgs);
            return corruptedArchiveError();
        }
        
        // check if filename appears in validArgs
        char shouldCopy = (isDuplicateFile(filename->str,
                           validArgs->names,
                           validArgs->numNames) < 0);
        
        // write filename and file size
        if(shouldCopy)
        {
            fwrite(filename->str,
                   sizeof(char),
                   filename->len,
                   tempArchive);
            fwrite(&fileSize, sizeof(unsigned int), 1, tempArchive);
            newNumFiles++;
        }
        
        // read file contents and write to tempArchive if shouldCopy
        for(unsigned int j = 0; j < fileSize; j++)
        {
            int c = fgetc(oldArchive);
            if(c == EOF)
            {
                fclose(oldArchive);
                fclose(tempArchive);
                unlink(TEMP_ARCHIVE_NAME);
                charBufferDelete(filename);
                fileListDelete(validArgs);
                return corruptedArchiveError();
            }
            else if(shouldCopy)
            {
                fputc(c, tempArchive);
            }
        }
    }
    
    // append new files to the end of tempArchive
    for(unsigned int i = 0; i < validArgs->numNames; i++)
    {
        if(isDuplicateFile(validArgs->names[i], validArgs->names, i) >= 0)
        {
            continue;
        }
        
        // call stat on the file
        if(stat(validArgs->names[i], &fileStat) < 0)
        {
            fileOpenError(validArgs->names[i]);
            continue;
        }
        
        // check if directory
        dir = opendir(validArgs->names[i]);
        if(dir)
        {            
            // write directory name to archive
            fwrite(validArgs->names[i],
                   sizeof(char),
                   strlen(validArgs->names[i]) + 1,
                   tempArchive);
            
            // write directory size (zero) to archive
            fileSize = 0;
            fwrite(&fileSize, sizeof(unsigned int), 1, tempArchive);
            
            newNumFiles++;
            
            closedir(dir);
        }
        else
        {
            // add this regular file to tempArchive
            fileToAdd = fopen(validArgs->names[i], "rb");
            fileSize = fileStat.st_size;
            
            writeFileToArchive(fileToAdd,
                               validArgs->names[i],
                               fileSize,
                               tempArchive);
            
            fclose(fileToAdd);
            
            // update numFiles
            newNumFiles++;
        }
    }
    
    finalizeArchive(oldArchive, archiveName, tempArchive, newNumFiles);
    
    // clean-up
    charBufferDelete(filename);
    fileListDelete(validArgs);
    return SUCCESS;
}