keepassxc

Форк
0
/
ShareImport.cpp 
104 строки · 3.8 Кб
1
/*
2
 *  Copyright (C) 2019 KeePassXC Team <team@keepassxc.org>
3
 *
4
 *  This program is free software: you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation, either version 2 or (at your option)
7
 *  version 3 of the License.
8
 *
9
 *  This program is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17
#include "ShareImport.h"
18
#include "core/Merger.h"
19
#include "format/KeePass2Reader.h"
20
#include "keeshare/KeeShare.h"
21
#include "keys/PasswordKey.h"
22

23
#include <QBuffer>
24
#include <minizip/unzip.h>
25

26
namespace
27
{
28
    QByteArray readZipFile(void* uf)
29
    {
30
        QByteArray data;
31
        int bytes, bytesRead = 0;
32
        unzOpenCurrentFile(uf);
33
        do {
34
            data.resize(data.size() + 8192);
35
            bytes = unzReadCurrentFile(uf, data.data() + bytesRead, 8192);
36
            if (bytes > 0) {
37
                bytesRead += bytes;
38
            }
39
        } while (bytes > 0);
40
        unzCloseCurrentFile(uf);
41
        data.truncate(bytesRead);
42
        return data;
43
    }
44
} // namespace
45

46
ShareObserver::Result ShareImport::containerInto(const QString& resolvedPath,
47
                                                 const KeeShareSettings::Reference& reference,
48
                                                 Group* targetGroup)
49
{
50
    QByteArray dbData;
51

52
    auto uf = unzOpen64(resolvedPath.toLatin1().constData());
53
    if (uf) {
54
        // Open zip share, extract database portion, ignore signature file
55
        char zipFileName[256];
56
        auto err = unzGoToFirstFile(uf);
57
        while (err == UNZ_OK) {
58
            unzGetCurrentFileInfo64(uf, nullptr, zipFileName, sizeof(zipFileName), nullptr, 0, nullptr, 0);
59
            if (QString(zipFileName).compare(KeeShare::containerFileName()) == 0) {
60
                dbData = readZipFile(uf);
61
            }
62
            err = unzGoToNextFile(uf);
63
        }
64
        unzClose(uf);
65
    } else {
66
        // Open KDBX file directly
67
        QFile file(resolvedPath);
68
        if (!file.open(QIODevice::ReadOnly)) {
69
            qCritical("Unable to open file %s.", qPrintable(reference.path));
70
            return {reference.path, ShareObserver::Result::Error, file.errorString()};
71
        }
72
        dbData = file.readAll();
73
        file.close();
74
    }
75

76
    QBuffer buffer(&dbData);
77
    buffer.open(QIODevice::ReadOnly);
78

79
    KeePass2Reader reader;
80
    auto key = QSharedPointer<CompositeKey>::create();
81
    key->addKey(QSharedPointer<PasswordKey>::create(reference.password));
82
    auto sourceDb = QSharedPointer<Database>::create();
83
    sourceDb->setEmitModified(false);
84
    if (!reader.readDatabase(&buffer, key, sourceDb.data())) {
85
        qCritical("Error while parsing the database: %s", qPrintable(reader.errorString()));
86
        return {reference.path, ShareObserver::Result::Error, reader.errorString()};
87
    }
88
    sourceDb->setEmitModified(true);
89

90
    qDebug("Synchronize %s %s with %s",
91
           qPrintable(reference.path),
92
           qPrintable(targetGroup->name()),
93
           qPrintable(sourceDb->rootGroup()->name()));
94

95
    Merger merger(sourceDb->rootGroup(), targetGroup);
96
    merger.setForcedMergeMode(Group::Synchronize);
97
    merger.setSkipDatabaseCustomData(true);
98
    auto changelist = merger.merge();
99
    if (!changelist.isEmpty()) {
100
        return {reference.path, ShareObserver::Result::Success, ShareImport::tr("Successful import")};
101
    }
102

103
    return {};
104
}
105

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.